动态路由匹配
路径参数
很多时候,我们需要将给定匹配模式的路由映射到同一个组件。例如,我们可能有一个 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,
})