Skip to content

动态路由匹配

路径参数

很多时候,我们需要将给定匹配模式的路由映射到同一个组件。例如,我们可能有一个 User 组件,它应该对所有用户进行渲染,但用户 ID 不同。在 Vue Router 中,我们可以在路径中使用一个动态字段来实现,我们称之为 路径参数

ts
import User from './User.vue'

// 这些都会传递给 `createRouter`
const routes = [
  // 动态字段以冒号开始
  //现在像 /users/johnny 和 /users/jolyne 这样的 URL 都会映射到同一个路由。
  { path: '/users/:id', component: User },
]

路径参数 用冒号 : 表示。当一个路由被匹配时,它的 params 的值将在每个组件中以 route.params 的形式暴露出来

vue
<template>
  <div>
    <!-- 当前路由可以通过 $route 在模板中访问 -->
    User {{ $route.params.id }}
  </div>
</template>

你可以在同一个路由中设置有多个 路径参数,它们会映射到 $route.params 上的相应字段。例如:

匹配模式匹配路径route.params
/users/:username/users/eduardo{ username: 'eduardo' }
/users/:username/posts/:postId/users/eduardo/posts/123{ username: 'eduardo', postId: '123' }

响应路由参数变化

使用带有参数的路由时需要注意的是,当用户从 /users/johnny 导航到 /users/jolyne 时,相同的组件实例将被重复使用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会被调用

要对同一个组件中参数的变化做出响应的话,你可以简单地 watch $route 对象上的任意属性,在这个场景中,就是 $route.params

vue
<script setup>
import { watch } from 'vue'
import { useRoute } from 'vue-router'

const route = useRoute()

watch(() => route.params.id, (newId, oldId) => {
  // 对路由变化做出响应...
})
</script>

捕获所有路由或 404 Not found 路由

定义捕获所有路由

当用户访问了一个 未定义的路径 时(比如你没有在路由表中注册 /abcxyz),Vue Router 默认是不会渲染任何内容的。

为了处理这种情况(即“找不到页面”或“404”),我们需要定义一个 兜底路由(catch-all route) 来捕获所有未匹配的路径。

通过设置一个特殊的 动态参数匹配规则

ts
const routes = [
  // ✅ 匹配所有路径的“404”路由
  {
    path: '/:pathMatch(.*)*',
    name: 'NotFound',
    component: NotFound,
  },
]
  • :pathMatch → 路径参数名。

  • (.*) → 使用正则表达式匹配任意字符(包括 /)。

  • * → 允许重复匹配,确保任何深层路径都能被捕获。

访问被捕获的路径信息

匹配到这个路由时,路径会被保存在:

ts
$route.params.pathMatch

例如:

访问路径$route.params.pathMatch
/abc'abc'
/foo/bar['foo', 'bar'] (被拆分成数组)

重定向到 404 页面

如果想从别的逻辑中跳转到 404,可以这样:

ts
router.push({
  name: 'NotFound',
  params: { pathMatch: ['some', 'wrong', 'path'] },
})

也可以保留完整URL:

ts
router.push({
  name: 'NotFound',
  params: { pathMatch: $route.path.substring(1).split('/') },
  query: $route.query,
  hash: $route.hash,
})