# 一、路由参数
在《vue 路由(上)》中,我们已经大概猜到了,其实<router-link>
最终还是会被渲染为<a>
标签在页面中展示。
提示
其实在讲到$route
和$router
,就可以学习路由参数的相关知识了,但使用嵌套路由的方式会让我们看的更加清楚。
# 1、$route 思考
打印路由组件实例 vc 上的 $route 的字体颜色为什么是暗色的?
因为
$route
是一个 Vue.js 响应式对象,$route
中的属性值可以动态地改变
![](https://blog-cloudbed.oss-cn-chengdu.aliyuncs.com/note-taking/20230418201933.png)
# 2、查询参数 query ✨
$route.query
在使用 vue-router 时,我们可以对待显示的路由组件进行数据传递(类似于发起 get 请求 🤔)
简单演示
<!-- 跳转控制区域 -->
<ul class="nav">
<li>
<router-link to="/part1?title=part1">part1</router-link>
</li>
</ul>
- 路由组件 PartOne.vue
<template>
<div>
<h4>{{ $route.query.title }}</h4>
<p>
开辟鸿蒙,谁为情种?都只为风月情浓。趁着这奈何天,伤怀日,寂寥时,试遣愚衷。因此上,演出这怀金悼玉的《红楼梦》。
</p>
</div>
</template>
- 模板字符串方式
<!-- 跳转控制区域 -->
<ul class="nav">
<li v-for="item in titleList">
<!-- 动态绑定v-bind -->
<router-link :to="`/part1?title=${item.title}`">part1</router-link>
</li>
</ul>
- 对象方式(复杂情况推荐 👍 使用)
<!-- 跳转控制区域 -->
<ul class="nav">
<li v-for="item in titleList">
<!-- 动态绑定v-bind -->
<router-link
:to="
{
path: 'part1',
query: {
title: item.title
}
}"
>
part1
</router-link>
</li>
</ul>
# 3、name 属性
在上面,如果我们使用对象方式的话,处理能是结构显示更加清晰,还有一个优点:简化嵌套路由的路径名书写。
即使用 name 属性 代替 path 属性,来简化书写 —— 命名路由
具体使用
export default new VueRouter({
routes: [
{
path: '/',
redirect: '/part1'
},
{
path: '/part1',
component: () => import('../page/PartOne.vue'),
redirect: '/part1/one',
children: [
{
// 使用命名👀路由
name: 'one',
path: 'one',
component: () => import('../page/One.vue')
},
{
name: 'two',
path: 'two',
component: () => import('../page/Two.vue')
}
]
}
// ……
]
})
- 路由组件 PartOne.vue
<!-- 1、跳转控制区域 -->
<!-- 以前 -->
<span><router-link to="/part1/one">one</router-link></span>
<!-- 现在 -->
<span><router-link :to="{name: 'two'}">two</router-link></span>
# 4、路径参数 params 🎈
对应路径参数,我们同样可以将它进行动态化处理:
提示
使用 params 时,要多一个了路由配置的步骤
① 路由配置
export default new VueRouter({
routes: [
{
path: '/',
redirect: '/part1'
},
{
// 路径参数 占位
path: '/part1/:id',
component: () => import('../page/PartOne')
}
]
})
② 传递参数
- 模板字符串方式(推荐 👍 使用)
<!-- 跳转控制区域 -->
<ul class="nav">
<li v-for="item in idList">
<!-- 动态绑定v-bind -->
<router-link :to="`/part1/${item.id}`">part1</router-link>
</li>
</ul>
- 对象方式(有个坑)
提示
使用 params 的对象写法时,不能使用 path 属性,转而要使用 name 属性才效
<!-- 跳转控制区域 -->
<ul class="nav">
<li v-for="item in idList">
<!-- 动态绑定v-bind -->
<router-link
:to="
{
name: 'part1',
params: {
id: item.id
}
}"
>
part1
</router-link>
</li>
</ul>
③ 获 params 参数
- 路由组件 PartOne.vue
<template>
<div>
<h4>{{ $route.params.id }}</h4>
</div>
</template>
<script>
export default {
create() {
console.log(this.$route.params.id)
}
// 特殊情况
// beforeRouteUpdate(to, from) {
// console.log(to.params.id)
// }
// vue3中
// setup() {
// const route = useRoute()
// console.log(route.params.id)
// }
}
</script>
# 5、props 属性
看到前面我们获取数据时,通常都是直接单个单个的使用$route.params.title
或者 $route.query.title
来获取数据,有没有一种使用直接 vuex 数据的感觉,但 vuex 为我们提供了辅助函数对传来是数据进行管理。
那 vue-router 中用没有类似的功能呢?
答案
知识回顾:
- 组件的 props 参数:在父组件中使用 自定义属性 向子组件传递数据,然后子组件使用 vc 上的 props 属性进行接收。
其实,vue-router 支持我们使用 props 将组件和路由解耦:
- 路由的 props 参数:在路由配置中可以使用的 props 属性值会传向 ✍ 指定的路由组件中
export default new VueRouter({
routes: [
{
path: '/',
redirect: '/part1'
},
// 1、对象写法(静态数据)
{
path: '/part1',
component: () => import('../page/PartOne.vue'),
// title值被指定死了😒
props: { title: 'part1' }
},
// 2、布尔值写法(动态数据) ---》 仅限params传参
{
path: '/part2/:title',
component: () => import('../page/PartTwo.vue'),
// 这里的props属性值会传给 路由组件PartOne
props: true
},
// 3、函数写法(动态数据) ---》 解除params传参限制🍗
{
path: '/part3',
component: () => import('../page/PartThree.vue'),
// 这里的props属性值会传给 路由组件PartOne
// props($route) {
// return { title: $route.query.title }
// }
props({ query }) {
return { title: query.title }
}
}
]
})
- 路由组件 PartOne.vue
export default {
name: 'PartOne',
props: ['title']
}
# 二、元信息 meta
# 1、与 props 区别
-props
是将参数通过组件实例的 props
属性传递给组件,它的作用是将参数作为组件的属性来传递。
-meta
是将参数作为元数据存储在路由中,它的作用是在路由配置中添加一些自定义的数据或标记,供路由拦截器或其他插件使用。
记忆
换个角度讲,mate 就是 props 中对象写法形式类似,用于静态数据。
export default new VueRouter({
routes: [
// 1、对象写法(静态数据)
{
path: '/part1',
component: () => import('../page/PartOne.vue'),
// title值被指定死了😒
props: { title: 'part1' }
}
]
})
# 2、meta 属性
- 示例 1
export default new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
children: [
{
path: 'bar1',
component: Bar1,
meta: {
requiresAuth: true, //1、用于权限登录,类似于前面的白名单✨页面放行
title: '首页' //2、用于路由跳转配套数据
}
}
]
}
]
})
- 示例 2
export default new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
children: [
{
path: 'bar1',
component: Bar1,
meta: {
requiresAuth: true,
title: '搜索'
list: ['foo','bar2'] // 面包屑效果
}
}
]
}
]
})
# 3、开发应用
- 路由拦截认证
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth && !auth.isAuthenticated()) {
next('/login')
} else {
next()
}
})