路由匹配
动态路由匹配
很多时候,我们需要将给定匹配模式的路由映射到同一个组件。例如,我们可能有一个 User 组件,它应该对所有用户进行渲染,但用户 ID 不同。在 Vue Router 中,我们可以在路径中使用一个动态字段来实现,我们称之为 路径参数
例如像 /part/小明
和 /part/小红
这样的 URL 需要映射到同一个路由,就可以像下面这样写。
// 这些都会传递给 `createRouter`
const routes = [
// 动态字段以冒号开始
{ path: "/part/:id", component: () => import("../views/Part.vue") },
];
2
3
4
5
路径参数 用冒号 :
表示。当一个路由被匹配时,它的 params
的值将在每个组件中以 this.$route.params
的形式暴露出来。因此,我们可以通过更新 Part
的模板来呈现当前的用户 ID
:
<template>
<div>
<p>寻找伙伴</p>
<div>User {{ $route.params.id }}</div>
</div>
</template>
2
3
4
5
6
你可以在同一个路由中设置有多个 路径参数,它们会映射到 $route.params
上的相应字段。例如:
匹配模式 | 匹配路径 | $route.params |
---|---|---|
/users/:username | /users/eduardo | { username: 'eduardo' } |
/users/:username/posts/:postId | /users/eduardo/posts/123 | { username: 'eduardo', postId: '123' } |
除了 $route.params
之外,$route
对象还公开了其他有用的信息,如 $route.query
(如果 URL 中存在参数)、$route.hash
等。你可以在 API 参考中查看完整的细节。
声明式导航
基础使用
目标:可用全局组件 router-link 来替代 a 标签
- vue-router 提供了一个全局组件 router-link
- router-link 实质上最终会渲染成 a 链接 to 属性等价于提供 href 属性 (to 无需
#
) - router-link 提供了声明式导航高亮的功能 (自带类名)
<template>
<div>
<div class="footer_wrap">
<!-- <a href="#/find">发现音乐</a>-->
<!-- <a href="#/my">我的音乐</a>-->
<!-- <a href="#/part">朋友</a>-->
<router-link to="/find">发现音乐</router-link>
<router-link to="/my">我的音乐</router-link>
<router-link to="/part">朋友</router-link>
</div>
<div class="top">
<router-view></router-view>
</div>
</div>
</template>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
总结:链接导航,用 router-link 配合 to, 实现点击切换路由
跳转传参
目标:在跳转路由时,可以给路由对应的组件内传值
在 router-link
上的 to
属性传值,语法格式如下
/path?参数名=值
/path/值
– 需要路由对象提前配置path: "/path/参数名"
对应页面组件接收传递过来的值
route.query.参数名
route.params.参数名
1、新建 views/Part2.vue
- 接收路由上传递的参数和值
<template>
<div>
<p>我的好友</p>
<!-- query 查询?号后面的。params 是获取 url : 中的参数-->
<p>人名 (path --> query): {{ route.query?.name }}</p>
<p>人名 (?后参数 --> params): {{ route.params?.name }}</p>
</div>
</template>
<script setup>
// 目标:声明式导航 - 基础使用
// 本质:vue-router 提供的全局组件 "router-link" 替代 a 标签
// 1. router-link 替代 a 标签
// 2. to 属性 替代 href 属性
// 好处:router-link 自带高亮的类名 (激活时类名)
// 3. 对激活的类名做出样式的编写
import { useRoute } from "vue-router";
const route = useRoute();
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2、修改路由定义
const routes = [
{ path: "/find", component: () => import("../views/Find.vue") },
{ path: "/my", component: () => import("../views/My.vue") },
{ path: "/part", name: "Part", component: () => import("../views/Part.vue") },
{
path: "/part/:name", // 有:的路径代表要接收具体的值
component: () => import("../views/Part2.vue"),
},
];
2
3
4
5
6
7
8
9
3、修改 App.vue
进行跳转
<template>
<div>
<div class="footer_wrap">
<!-- <a href="#/find">发现音乐</a>-->
<!-- <a href="#/my">我的音乐</a>-->
<!-- <a href="#/part">朋友</a>-->
<router-link to="/find">发现音乐</router-link>
<router-link to="/my">我的音乐</router-link>
<router-link to="/part">朋友</router-link>
<router-link to="/part?name=小传">朋友 - 小传</router-link>
<router-link to="/part/小智?name=小智2">朋友 - 小智</router-link>
</div>
<div class="top">
<router-view></router-view>
</div>
</div>
</template>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
总结:
?key=value
用$route.query.key
取值/值
提前在路由规则/path/:key
用$route.params.key
取值query
是查询参数,params
是path
路径
在这个特定的场景中,我们在括号之间使用了自定义正则表达式,并将pathMatch
参数标记为可选可重复。这样做是为了让我们在需要的时候,可以通过将 path
拆分成一个数组,直接导航到路由:
捕获路由
常规参数只匹配 url 片段之间的字符,用 /
分隔。如果我们想匹配任意路径,我们可以使用自定义的 路径参数 正则表达式,在 路径参数 后面的括号中加入 正则表达式 :
const routes = [
// 将匹配所有内容并将其放在 `$route.params.pathMatch` 下
{ path: "/:pathMatch(.*)*", name: "NotFound", component: NotFound },
// 将匹配以 `/user-` 开头的所有内容,并将其放在 `$route.params.afterUser` 下
{ path: "/user-:afterUser(.*)", component: UserGeneric },
];
2
3
4
5
6
案例 - 404 页面
默认给一个 404 页面
语法:路由最后,path 匹配*(任意路径) – 前面不匹配就命中最后这个,显示对应组件页面
1、创建 NotFound
页面
<template>
<div>404 资源不存在</div>
</template>
2
3
2、在 src/router/index.js
- 修改路由配置
const routes = [
// ...省略了其他配置
// 404 在最后 (规则是从前往后逐个比较 path)
{
path: "/:pathMatch(.*)*",
component: () => import("../views/NotFound.vue"),
},
];
2
3
4
5
6
7
8
总结:如果路由未命中任何规则,给出一个兜底的 404 页面