目录
Vue路由守卫
Vue Router 守卫是 Vue Router 库中的一项功能,它提供了一种方法来控制对 Vue.js 应用程序中不同路由的访问。它们允许您在允许导航到特定路线之前检查某些条件(例如身份验证或访问权限)。Vue Router 中有四种类型的守卫:beforeEach、beforeResolve、afterEach 和 beforeEnter。它们可用于执行重定向到不同路线、阻止导航或在继续之前修改路线参数等操作。
路由守卫,简单理解来说就是,当用户要进行一些操作时,我需要用户的一些信息或数据或行为,我判断过后,才会同意用户进行操作,说到这里,我想大家心里都或多或少有点理解了吧,官方一点的解释就是进行操作的鉴权,当操作与之条件匹配时,操作成功,当操作与之不匹配时,操作终止,作用就是是对路由进行权限控制。
在Vue中,路由守卫分为三种:全局路由守卫、独享路由守卫以及组件内路由守卫
全局路由守卫
全局路由守卫,顾名思义,一旦配置,那么作用范围就是所有的路由,全局路由又分为全局前置守卫和全局后置守卫
全局前置守卫
全局前置守卫,组件初始化时调用,每次路由切换之前调用,路由切换之前指的就是,举个例子说,当前我在A路由组件,我要切换到B路由组件,那么前置路由守卫就是在我点了切换按钮,但B路由组件还没有被呈现在页面上的时候被调用。
//全局前置守卫
router.beforeEach((to,from,next) =>{
//第一个参数to,包含的内容是切换后的路由对象,也就是跳转后的路由对象
//第二个参数from,包含的内容的是切换前的路由对象,也就是跳转前的路由对象
//第三个参数next(),是否往下执行,执行的话,如果不写的话路由就不会跳转,操作将会终止
})
全局后置守卫
全局后置守卫,组件初始化时调用,每次路由切换之后调用,路由切换之后指的就是,举个例子说,当前我在A路由组件,我要切换到B路由组件,那么前置路由守卫就是在我点了切换按钮B路由组件呈现到页面中后被调用。
router.afterEach((to,from) =>{
//第一个参数to,包含的内容是切换后的路由对象,也就是跳转后的路由对象
//第二个参数from,包含的内容的是切换前的路由对象,也就是跳转前的路由对象
实例代码:
下面我写的实例是当时看网课尚硅谷老师教的,结合浏览器的Local Storage做出鉴权操作:
主要的就是src/store/index.js
文件中的配置src/store/index.js:
//该文件用于创建整个应用的router
//首先,需要引用vue-router
import VueRouter from "vue-router";
//引入路由组件
import TestA from '../pages/TestA'
import TestB from '../pages/TestB'
// 引入二级路由组件
import TestBHzw from '../pages/TestBHzw'
import TestBHyrz from '../pages/TestBHyrz'
import DataList from '../pages/DataList'
//创建并暴露一个VueRouter
const router = new VueRouter({
routes:[
//配置路由路径和路由组件
{
//这里的路径可自由定义,但是为了初学者好理解,我就采用和组件同样的命名,防止在写路径的时候搞混
name:'导航一',
path:'/TestA',
component:TestA, //要跳转到的组件
children:[
{
// 给二级路由起名字
name:'DataName',
path:'DataList/:introduce', //起到占位作用
component:DataList
}
]
},
{
name:'导航二',
path:'/TestB',
component:TestB,
meta:{isAuth:true,},
// 配置二级路由
children:[
{
path:'TestBHzw', //重点注意,不要加 /
component:TestBHzw
},
{
path:'TestBHyrz',
component:TestBHyrz
}
]
}
]
})
//全局前置路由,配合浏览器localStorage进行鉴权操作
router.beforeEach((to, from, next) =>{
//首先,我们先看一看to和from参数,next就是执行的意思,不写页面是不会跳转的
// console.log(to, from);
if(to.meta.isAuth){ //判断是否需要鉴权
if(localStorage.getItem('name') === '张三'){
next();
}else{
alert('不好意思,姓名不对,没有权限');
}
}else{
next()
}
})
// 全局后置路由,简单写一个弹窗,在进入每一个路由组件后弹出一句话
router.afterEach(() =>{
alert('欢迎你!!');
})
export default router;
TestA.vue:
<template>
<div>
<h4>著名动漫简介</h4>
<ul>
<li v-for="i in DataList" :key="i.id">
<!-- 使用params参数传递动态参数 注意:params传递参数必须配合name属性-->
<router-link :to="{
name:'DataName',
params:{
introduce:i.introduce
}
}">{{i.name}}</router-link>
</li>
</ul>
<router-view></router-view>
</div>
</template>
<script>
export default {
name:'TestA',
data(){
return{
DataList:[
{
id:1,
name:'《海贼王》',
introduce:'《航海王》是日本漫画家尾田荣一郎作画的少年漫画作品,于1997年7月22日在集英社《周刊少年Jump》开始连载。改编的电视动画《航海王》于1999年10月20日起在富士电视台首播。'
},
{
id:2,
name:'《火影忍者》',
introduce:'电视动画《火影忍者》改编自日本漫画家岸本齐史的同名漫画,2002年10月3日在东京电视台系列全6局、岐阜放送首播,共220话;第二季《火影忍者疾风传》于2007年2月15日-2017年3月23日在东京电视台播出,共500话;累计全720话。'
},
{
id:3,
name:'《斗破苍穹》',
introduce:'《斗破苍穹》是一部由阅文集团旗下起点中文网作家天蚕土豆同名玄幻长篇经典小说改编的动画。该动画第一季已于2017年1月7日在腾讯视频上映,bilibili同步跟播,共十二集。'
},
{
id:4,
name:'《鬼灭之刃》',
introduce:'《鬼灭之刃》是日本漫画家吾峠呼世晴所著的少年漫画,自2016年2月15日—2020年5月11日在集英社《周刊少年Jump》上连载。已完结。'
}
]
}
}
}
</script>
<style scoped>
h4{
text-align: center;
}
a{
text-decoration: none;
}
.active:visited{
color: brown;
}
</style>
TestB.vue:
<template>
<div>
<h4>我是内容二</h4>
<!-- 多级路由 -->
<div class="box">
<!-- 此处路径一定要写完整路径 -->
<router-link to="/TestB/TestBHzw" active-class="active">点击查看《海贼王的简介》</router-link>
<router-link to="/TestB/TestBHyrz" active-class="active">点击查看《火影忍者的简介》</router-link>
<hr>
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {
name:'TestB',
}
</script>
<style scoped>
h4{
text-align: center;
}
.box{
text-align: center;
}
a{
text-decoration: none;
}
.active:visited{
color: brown;
}
</style>
DataList.vue:
<template>
<div>
<ul>
<!-- 采用插值语法就可以拿到父级路由中的数据 -->
<li>{{$route.params.introduce}}</li>
</ul>
</div>
</template>
<script>
export default {
name:'DataList'
}
</script>
<style>
</style>
TestBHzw.vue和TestBHyrz.vue的结构是一样的,就不重复展示了:
<template>
<div>
<p>
电视动画《火影忍者》改编自日本漫画家岸本齐史的同名漫画,
2002年10月3日在东京电视台系列全6局、岐阜放送首播,共220话;
第二季《火影忍者疾风传》于2007年2月15日-2017年3月23日在东京电视台播出,共500话;累计全720话。
</p>
</div>
</template>
<script>
export default {
name:'TestBHyrz'
}
</script>
<style>
</style>
当然,想要配置路由守卫,前提就是把基本的路由配置好
因为不管是前置守卫和后置守卫,都有三个参数,netx()我们已经说过,不写的话不会往下一步走,
那么我们输出一下to和from看看
当前页面是初始化页面,所以此时输出的to, from都是空对象。
当我们点击 “导航一” 时,to里面有了新内容,为什么from没有呢,是因为我们处于最顶层初始化页面,在我们点击之前,我们是没有路由的,所以只能捕获到我们要去往哪一个路由组件,匹配不到我们来自哪一个路由组件
我们处于第一级路由的 “导航一” 跳往 “导航二” 时,此时的to和from就显而易见了
要想配合localStorage来实现鉴权,我们就要先在浏览器中给他一对key—value
现在我们就可以把鉴权的操作写在前置守卫中了
后置守卫就简单实现一下进入组件后实现弹窗
此时我们切换到“导航二”组件时,前置路由守卫已经拒绝了我们的访问,那是因为我在鉴权操作中,匹配的名字是“张三”
把名字改为“王五”后,我们可以正常访问“导航二”组件了
独享守卫
组件独享守卫是在进入组件时被调用,区别就在于,想对那个路由进行权限控制就直接在其路由配置项中添加守卫,作用域也仅限于该路由
beforeEnter(to,from,next){
//第一个参数to,包含的内容是切换后的路由对象,也就是跳转后的路由对象
//第二个参数from,包含的内容的是切换前的路由对象,也就是跳转前的路由对象
//第三个参数next(),是否往下执行,执行的话,如果不写的话路由就不会跳转,操作将会终止
}
可自行去尝试,其实效果都是一样的,只不过,全局路由守卫服务的是所有路由组件,而独享路由守卫只服务于被配置的单个路由组件
组件内守卫
当使用路由规则进入该组件或离开该组件时,就会触发组件内守卫的调用,而组件内守卫的作用于范围也仅限于该组件
//进入守卫:通过路由规则,进入该组件时被调用
beforeRouteEnter (to, from, next) {
//第一个参数to,包含的内容是切换后的路由对象,也就是跳转后的路由对象
//第二个参数from,包含的内容的是切换前的路由对象,也就是跳转前的路由对象
//第三个参数next(),是否往下执行,执行的话,如果不写的话路由就不会跳转,操作将会终止
},
//离开守卫:通过路由规则,离开该组件时被调用
beforeRouteLeave (to, from, next) {
//第一个参数to,包含的内容是切换后的路由对象,也就是跳转后的路由对象
//第二个参数from,包含的内容的是切换前的路由对象,也就是跳转前的路由对象
//第三个参数next(),是否往下执行,执行的话,如果不写的话路由就不会跳转,操作将会终止
}
唯一不同于之前的就是
BeforeRouterLeave(),它并不像全局后置守卫一样在路由组件加载完成之后调用,而是在你切换出这个组件后被调用,也就是离开这个组件后被调用,在开发中,我们也可以使用BeforeRouterLeave() 来完成某些操作,比如当我要切换出该组件事,我希望该组件的操作能暂停,而不是一直运行,只有当我切换回该组件时,又再次运行,这样的操作就可以配合着beforeRouteEnter() 来完成,也可以提高应用的性能
总结
路由守卫在实际开发过程中是一个较为重要的知识点,其作用和功能在实际开发中也大大方便了我们的开发,在对用户鉴权操作时也提高了我们编写代码的小效率,以上就是我个人在学习时对路由守卫的理解和笔记。