四十一、Vue-Router使用
大约 6 分钟约 1833 字
(一)基本路由
1.安装 Vue-Router
- 在 2022 年 02 月 07 日,Vue3 成为了默认版本
- 即
npm i vue
直接安装的是 Vue3
- 即
- 同时 vue-router 也更新到了 v4
- 即
npm i vue-router
安装的是 VueRouter4
- 即
- vue-router4 只能在 Vue3 中使用
- Vue2 项目需要安装 vue-router3
npm i vue-router@3
2.应用插件
Vue.use(VueRouter);
3.编写 router 配置项
// 引入VueRouter
import VueRouter from "vue-router";
// 引入路由组件
import About from "../components/About";
import Home from "../components/Home";
// 创建router实例对象,去管理一组一组的路由规则
const router = new VueRouter({
routes: [
{
path: "/about",
component: About,
},
{
path: "/home",
component: Home,
},
],
});
// 暴露router
export default router;
4.实现切换
- active-class 可配置高亮样式
<router-link active-class="active" to="/about">About</router-link>
5.指定展示位置
<router-view></router-view>
几个注意点
- 路由组件通常存放在
pages
文件夹,一般组件通常存放在components
文件夹 - 通过切换,“隐藏”了的路由组件,默认是被销毁掉的,需要的时候再挂载
- 每个组件都有自己的
$route
属性,里面存储着自己的路由信息 - 整个应用只有一个
router
,可以通过组件的$router
属性获取到
(二)多级路由/嵌套路由
1.配置路由规则
- 使用 children 配置项
routes: [
{
path: "/about",
component: About,
},
{
path: "/home",
component: Home,
children: [
// 通过children配置子级路由
{
path: "news", // 子级路由路径一定不要写前缀/
component: News,
},
{
path: "messages",
component: Messages,
},
],
},
];
2.跳转
- 要写完整路径
<router-link to="/home/news">News</router-link>
(三)命名路由
1.作用
- 可以简化路由的跳转
2.使用
1)给路由命名
{
path: '/demo',
component: Demo,
children: [
{
path: 'test',
component: Test,
children: [
{
name: 'hello', // 给路由命名
path: 'welcome',
component: Hello
}
]
}
]
}
2)简化跳转
<!-- 简化前,需写完整的路径 -->
<router-link to="/demo/test/welcome">跳转</router-link>
<!-- 简化后,直接通过名字跳转 -->
<router-link :to="{name: 'hello'}">跳转</router-link>
<!-- 简化写法配合传递参数 -->
<router-link
:to="{
name: 'hello',
query: {
id: 666,
title: '你好'
}
}"
>
跳转
</router-link>
(四)路由的 query 参数
1.传递参数
<li v-for="m in messageList" :key="m.id">
<!-- 跳转路由并携带query参数,to的字符串写法 -->
<router-link :to="`/home/messages/detail?id=${m.id}&title=${m.title}`">{{ m.title }}</router-link>
<!-- 跳转路由并携带query参数,to的对象写法 -->
<router-link
:to="{
path: '/home/messages/detail',
query: {
id: m.id,
title: m.title,
},
}"
>
{{ m.title }}
</router-link>
</li>
2.接收参数
$route.query.id;
$route.query.title;
(五)路由的 params 参数
1.配置路由,声明接收 params 参数
{
path: '/home',
component: Home,
children: [
{
path: 'news',
component: News
},
{
component: Messages,
children: [
{
name: 'xiangqing',
path: 'detail/:id/:title', // 使用占位符声明接收params参数
component: Detail
}
]
}
]
}
2.传递参数
重要
路由携带 params 参数时,若使用 to 的对象写法,则不能使用 path 配置项
必须使用 name 配置项
<!-- 跳转并携带params参数,to的字符串写法 -->
<router-link to="/home/messages/detail/666/你好">跳转</router-link>
<!-- 跳转并携带params参数,to的对象写法 -->
<router-link
:to="{
name: 'hello',
params: {
id: 666,
title: '你好'
}
}"
>
跳转
</router-link>
3.接收参数
$route.params.title;
$route.params.id;
(六)路由的 props 配置
- 作用:让路由组件更方便地收到参数
{
name: 'xiangqing',
path: 'detail/:id/:title',
component: Detail,
// 第一种写法:props值为对象,该对象中所有的key-value的组合最终都会通过props传给Detail组件
props: {
a: 900
},
// 第二种写法:props值为布尔值,布尔值为true,则把路由收到的所有params参数通过props传给Detail组件
props: true,
// 第三种写法:props值为函数,该函数返回的对象中每一组key-value都会通过props传给Detail组件
props(route) {
return {
id: route.query.id,
title: route.query.title
}
}
}
<router-link>
的 replace 属性
(七)1.作用
- 控制路由跳转时操作浏览器历史记录的模式
2.浏览器的历史记录有两种写入方式
- 分别为
push
和replace
push
是追加历史记录replace
是替换当前记录
- 路由跳转的时候默认是
push
replace
模式
3.开启 <router-link replace ......>News</router-link>
(八)编程式路由导航
1.作用
- 不借助
<router-link>
实现路由跳转,让路由跳转更加灵活
2.具体编码
// $router的两个API
this.$router.push({
name: "xiangqing",
params: {
id: m.id,
title: m.title,
},
});
this.$router.replace({
name: "xiangqing",
params: {
id: m.id,
title: m.title,
},
});
// 前进
this.$router.forward();
// 后退
this.$router.back();
/**
* 可前进也可后退
* 根据函数调用时传递的参数
* 正数->前进,负数->后退
*/
this.$router.go(1);
(九)缓存路由组件
1.作用
- 让不展示的路由组件保持挂载,不被销毁
2.具体编码
- includes 接收的是 组件名 ,不是路由规则的 name
- 不配置 includes 则所有展示在 keep-alive 标签中的组件都保持挂载
<!-- 缓存所有显示在keep-alive中的组件 -->
<keep-alive>
<router-view></router-view>
</keep-alive>
<!-- 缓存一个路由组件 -->
<keep-alive include="News">
<router-view></router-view>
</keep-alive>
<!-- 缓存多个路由组件 -->
<keep-alive :include="['News', 'Messages']">
<router-view></router-view>
</keep-alive>
(十)两个新的生命周期钩子
1.作用
- 路由组件所独有的两个钩子
- 用于捕获路由组件的激活状态
2.具体名字
activated
:路由组件被激活时触发deactivated
:路由组件失活时触发
(十一)路由守卫
1.理解
- 御前侍卫:保护君王的安全
- 路由守卫:保护路由的安全(权限)
2.作用
- 对路由进行权限控制
3.分类
- 全局守卫
- 独享守卫
- 组件内守卫
4.全局守卫
1)全局前置路由守卫
/**
* 1.初始化的时候被调用
* 2.每次路由切换之前被调用
*/
router.beforeEach((to, from, next) => {
console.log("beforeEach", to, from);
if (to.meta.isAuth) {
// 判断当前路由是否需要进行权限控制
if (localStorage.getItem("school") === "atguigu") {
// 权限控制的具体规则
next(); // 放行
} else {
alert("暂无权限查看!");
// next({name: 'guanyu'});
}
} else {
next(); // 放行
}
});
2)全局后置路由守卫
/**
* 1.初始化的时候被调用
* 2.每次路由切换之后被调用
*/
router.afterEach((to, from) => {
console.log("afterEach", to, from);
if (to.meta.title)
document.title = to.meta.title; // 修改网页的title
else document.title = "vue_test";
});
5.独享守卫
beforeEnter: (to, from, next) => {
console.log("beforeEnter", to, from);
if (to.meta.isAuth) {
if (localStorage.getItem("school") === "atguigu") {
next();
} else {
alert("学校名不对,无权限查看!");
}
} else {
next();
}
};
6.组件内守卫
// 进入守卫,通过路由规则,进入该组件时被调用
beforeRouteEnter(to, from, next) {
......
},
// 离开守卫,通过路由规则,离开该组件时被调用
beforeRouteLeave(to, from, next) {
......
},
(十二)路由器的两种工作模式
1.哈希值
- 对于一个 url
localhost:8080/#/home/messages/detail
#
及其之后的内容表示 hash 值
- hash 值不会包含在 HTTP 请求中
- 即:hash 值不会带给服务器
2.分类
- 分为 history 模式与 hash 模式
- 默认使用的是 hash 模式
3.切换工作模式
// history模式
const router = new VueRouter({
mode: 'history',
routes: [{...}]
});
// hash模式
const router = new VueRouter({
mode: 'hash',
routes: [{...}]
});
4.hash 模式
- 地址中永远带着#号,不美观
- 若以后将地址通过第三方手机 app 分享,若 app 校验严格,则地址会被标记为不合法
- 兼容性较好
5.history 模式
- 地址干净,美观
- 兼容性和 hash 模式相比略差
- 应用部署上线时需要后端人员支持,解决刷新页面服务端 404 的问题