Props 注入

vitarx-router 支持将路由参数自动注入到组件的属性(props)中,让组件可以像接收普通 props 一样获取路由参数,而不必依赖 useRoute() 钩子。

默认行为

默认情况下,路由的 propstrue,路径中的动态参数会自动注入到组件 props:

tsx
// 路由配置
{ path: '/user/{id}', component: User }

// 组件接收 props
function User({ id }: { id: string }) {
  return <div>用户 ID:{id}</div>
}

访问 /user/123 时,User 组件会收到 id"123" 的 prop。

关闭注入

设置 props: false 禁用参数注入,组件需要通过 useRoute() 获取参数:

tsx
// 路由配置
{ path: '/user/{id}', component: User, props: false }

// 组件通过 useRoute 获取参数
import { useRoute } from 'vitarx-router'

function User() {
  const route = useRoute()
  return <div>用户 ID:{route.params.id}</div>
}

对象模式

props 可以设置为一个对象,将指定的键值对注入组件:

tsx
// 路由配置
{
  path: '/user/{id}',
  component: User,
  props: { showFooter: true, theme: 'dark' }
}

// 组件接收 props
function User({ id, showFooter, theme }: {
  id: string
  showFooter: boolean
  theme: string
}) {
  return (
    <div>
      <p>用户 ID:{id}</p>
      <p>主题:{theme}</p>
      {showFooter && <footer>页脚</footer>}
    </div>
  )
}

INFO

对象模式中的静态 props 会与路径参数合并,路径参数优先级更高。

函数模式

props 可以设置为一个函数,将路由信息转换为组件 props:

tsx
// 路由配置
{
  path: '/user/{id}',
  component: User,
  props: (route) => ({
    id: route.params.id,
    query: route.query
  })
}

// 组件接收转换后的 props
function User({ id, query }: {
  id: string
  query: Record<string, string>
}) {
  return (
    <div>
      <p>用户 ID:{id}</p>
      <p>查询参数:{JSON.stringify(query)}</p>
    </div>
  )
}

函数模式适合需要对路由参数进行转换或组合的场景。

命名视图的 Props

对于命名视图,props 需要以键值对形式为每个视图单独配置:

tsx
{
  path: '/dashboard',
  component: {
    default: Dashboard,
    sidebar: DashboardSidebar
  },
  props: {
    default: true,      // default 视图注入路径参数
    sidebar: false       // sidebar 视图不注入参数
  }
}

每个视图的 props 配置同样支持 boolean、对象和函数模式:

tsx
{
  path: '/dashboard',
  component: {
    default: Dashboard,
    sidebar: DashboardSidebar
  },
  props: {
    default: (route) => ({ id: route.params.id }),
    sidebar: { collapsed: true }
  }
}

全局配置

createRouterprops 选项可以设置全局默认值,优先级低于单条路由的 props 配置:

ts
const router = createRouter({
  routes: [...],
  props: true  // 全局默认注入路径参数
})

完整示例

tsx
import { createRouter } from 'vitarx-router'
import { lazy } from 'vitarx'

const router = createRouter({
  routes: [
    // 默认:注入路径参数
    {
      path: '/user/{id}',
      component: lazy(() => import('./pages/User.tsx'))
      // props: true(默认值)
    },
    // 关闭注入
    {
      path: '/settings',
      component: lazy(() => import('./pages/Settings.tsx')),
      props: false
    },
    // 对象模式
    {
      path: '/article/{slug}',
      component: lazy(() => import('./pages/Article.tsx')),
      props: { showComments: true }
    },
    // 函数模式
    {
      path: '/search',
      component: lazy(() => import('./pages/Search.tsx')),
      props: route => ({
        keyword: route.query.q as string,
        page: Number(route.query.page) || 1
      })
    },
    // 命名视图
    {
      path: '/dashboard',
      component: {
        default: lazy(() => import('./pages/Dashboard.tsx')),
        sidebar: lazy(() => import('./pages/DashboardSidebar.tsx'))
      },
      props: {
        default: true,
        sidebar: { collapsed: false }
      }
    }
  ]
})