路由匹配

本页介绍 vitarx-router 的路由匹配规则,包括静态路由、动态参数、查询参数和匹配记录。

匹配规则

静态路由

静态路由按照路径精确匹配:

ts
const routes = defineRoutes(
  { path: '/', component: Home },
  { path: '/about', component: About },
  { path: '/contact', component: Contact }
)

访问 /about 时,将匹配到 About 组件;访问 / 时,匹配到 Home 组件。

动态路由

路由路径支持动态参数,使用花括号 {param} 定义:

语法说明示例路径
{param}必填动态参数/user/{id}
{param?}可选动态参数/user/{id?}
ts
// 访问 /user/123 时,route.params.id 为 '123'
{ path: '/user/{id}', component: UserDetail }

关于动态参数的完整用法(参数约束、多参数组合等),请参阅 动态路由

路由参数

通过 useRoute() 获取当前路由信息,params 属性包含所有动态路径参数:

tsx
import { useRoute } from 'vitarx-router'

export default function User() {
  const route = useRoute()

  return <div>用户 ID:{route.params.id}</div>
}

路由参数具有响应性,可以监听其变化:

tsx
import { useRoute, watch } from 'vitarx-router'

export default function User() {
  const route = useRoute()

  watch(
    () => route.params.id,
    (newId, oldId) => {
      console.log(`用户 ID 从 #123;oldId} 变为 #123;newId}`)
    }
  )

  return <div>用户 ID:{route.params.id}</div>
}

查询参数

useRoute().query 包含当前 URL 的查询字符串参数:

ts
// 访问 /user?id=123&tab=profile
const route = useRoute()

console.log(route.query.id) // "123"
console.log(route.query.tab) // "profile"

查询参数同样具有响应性,适合在组件中动态响应 URL 变化。

Hash

useRoute().hash 返回当前 URL 的 hash 部分:

ts
// 访问 /about#section-1
const route = useRoute()

console.log(route.hash) // "#section-1"

如果 URL 没有 hash,则返回空字符串 ''

匹配记录

useRoute().matched 是一个数组,包含从根路由到当前路由的所有匹配记录。对于嵌套路由,数组中会包含每一层级的路由记录:

ts
const routes = defineRoutes({
  path: '/user/{id}',
  component: UserLayout,
  children: [
    { path: '/profile', component: UserProfile },
    { path: '/settings', component: UserSettings }
  ]
})

当访问 /user/123/profile 时:

ts
const route = useRoute()

console.log(route.matched.length) // 2
console.log(route.matched[0]) // UserLayout 的路由记录
console.log(route.matched[1]) // UserProfile 的路由记录

每条匹配记录包含以下关键信息:

属性说明
path路由路径
component路由对应的组件
meta路由元信息
params该层级解析的参数
beforeEnter路由独享守卫

完整示例

tsx
import { defineRoutes, createRouter, useRoute, watch } from 'vitarx-router'
import { createApp } from 'vitarx'
import App from './App.jsx'
import Home from './pages/Home.jsx'
import User from './pages/User.jsx'
import Post from './pages/Post.jsx'

const routes = defineRoutes(
  { path: '/', component: Home },
  { path: '/user/{id}', component: User },
  { path: '/post/{slug}', component: Post, pattern: { slug: /^[a-z0-9-]+$/ } }
)

const router = createRouter({ routes })

createApp(App).use(router).mount('#root')
tsx
// pages/User.jsx
import { useRoute, watch } from 'vitarx-router'

export default function User() {
  const route = useRoute()

  watch(
    () => route.params.id,
    id => {
      console.log('当前用户 ID:', id)
    }
  )

  return (
    <div>
      <h1>用户详情</h1>
      <p>ID:{route.params.id}</p>
      <p>查询参数:{JSON.stringify(route.query)}</p>
      <p>Hash:{route.hash}</p>
    </div>
  )
}