十一、【Vue-Router】路由守卫

十一、路由守卫

本文记录 5 个守卫:

  1. 全局守卫 2 个
    1. beforeEach:全局前置路由守卫
    2. afterEach:全局后置路由守卫
  2. 私有守卫 1 个
    1. beforeEnter:路由私有守卫
  3. 组件内守卫 2 个
    1. beforeRouteEnter:进入当前组件时调用
    2. beforeRouteLeave:离开当前组件时被调用

1、需求

Others 和 Home 人人都可访问, News 和 Message 必须是登录的用户才能访问


2、功能一览

在这里插入图片描述


3、思考一波

需求就是加权限,权限怎么加合适呢?

在路由跳转的时候加最合适,那应该怎么加呢?

挂上拦截器在路由跳转的时候拦截检查,那这个所谓的拦截器是什么呢?

全局前置-路由守卫 beforeEach


4、全局前置-路由守卫 beforeEach

1、router/index.js

// 该文件专门用于创建整个应用的路由器
import VueRouter from 'vue-router'
//引入组件
import Others from '../views/Others'
import Home from '../views/Home'
import News from '../views/News'
import Message from '../views/Message'
import Details from '../views/Details'

//创建一个路由器
const router =  new VueRouter({
	routes:[ // 路由器管理的是什么呀?肯定是路由啊,全在这了!
		{ // 一级路由
			name: 'other',
			path: '/others',
			component: Others
		},
		{ // 一级路由
			path: '/home',
			component: Home,
			children:[ // 为什么是数组?你凭什么断定他就只能生一个娃?
				{ // 二级路由
					name: 'news',
					path: 'news', // 数组里的就不用加'/'了,路由器遍历的时候自动加上了
					component: News,
				},
				{ // 二级路由
					name: 'message',
					path: 'message',
					component: Message,
					children: [
						{ // 三级路由
							name: 'detail',
							path: 'details/:id/:title/:desc', // 配置占位符
							component: Details,
							props(route){ // router每次调的时候会把 $route 传进来,你想怎么取就怎么取!
								return {
									id: route.params.id,
									title: route.params.title,
									desc: route.params.desc
								}
							}
						},
					]
				}
			]
		}
	]
})

// 全局前置路由守卫(初始化和每次路由跳转之前调用)
router.beforeEach((to, from, next)=>{
	console.log('to===>', to)
	console.log('from===>', from)
	console.log('next===>', next)
	next()
})

// 暴露路由器
export default router

2、Result

在这里插入图片描述


5、优化 beforeEach

1、router/index.js

// 创建一个白名单
const whiteList = ['/others', '/home']

// 全局前置路由守卫(初始化和每次路由跳转之前调用)
router.beforeEach((to, from, next)=>{
	// 白名单直接放行
    if(whiteList.includes(to.path)){
        next()
    } else if(sessionStorage.getItem('id')){ // 是否登录,登录了会把id存到sessionStorage
        next()
	} else {
		alert('暂无权限!')
	}
})

2、Result

在这里插入图片描述


6、另一种思路:路由元数据 meta

我可不可以在配置路由的时候给每个路由挂个boolean类型参数peiqi,我在守卫里只要判断每个to的peiqi的真假就决定是否放行?请参观to的属性:

在这里插入图片描述


7、践行新思路

router/index.js

// ...
//创建一个路由器
const router =  new VueRouter({
	routes:[ // 路由器管理的是什么呀?肯定是路由啊,全在这了!
		{ // 一级路由
			name: 'other',
			path: '/others',
			component: Others,
            meta: {
                peiqi: true
            }
		},
		{ // 一级路由
			path: '/home',
			component: Home,
            meta: {
                peiqi: true
            }
			children:[ 
                // ... 其余的不配meta
			]
		}
	]
})

// 全局前置路由守卫(初始化和每次路由跳转之前调用)
router.beforeEach((to, from, next)=>{
	// 有peiqi且为true的放行!
    if(to.meta.peiqi){
        next()
    } else if(sessionStorage.getItem('id')){ // 是否登录,登录了会把id存到sessionStorage
        next()
	} else {
		alert('暂无权限!')
	}
})

// 暴露路由器
export default router

8、全局后置-路由守卫 afterEach

有前置守卫,必然就有后置守卫!

这里提出新需求:每次跳转后页签标题要和当前组件契合

1、router/index.js

// ...
//创建一个路由器
const router =  new VueRouter({
	routes:[
		{
			name: 'other',
			path: '/others',
			component: Others,
            meta: {
                peiqi: true,
                title: '其他'
            }
		},
		{
			path: '/home',
			component: Home,
            meta: {
                peiqi: true,
                title: '主页'
            }
			children:[ 
                // ... 其余的meta也配title,但是篇幅过长自行体会
			]
		}
	]
})

// ... 略

// 全局后置路由守卫(初始化和每次路由跳转之后调用)
// 后置没有next参数,走到这说明前置守卫已经放行,这里不再多此一举
router.afterEach((to, from)=>{
	document.title = to.meta.title || 'Mr.Wang!'
})

// 暴露路由器
export default router

2、Result

在这里插入图片描述


9、独享路由守卫 beforeEnter

有全局的就有独享的,没错就是 beforeEnter!(注意!独享守卫只有前置,没有后置!)

执行顺序:beforeEach–>beforeEnter–>afterEach

这里提出新需求:跳转到 Others 的时候 title 改为 佩奇!

这里有大聪明就想问了,我直接把 Others 路由的 meta.title 改成 " 佩奇 " 不就得了吗?

咋滴,你就不想学 beforeEnter 了呗?

1、router/index.js

// ...
//创建一个路由器
const router =  new VueRouter({
	routes:[
		{
			name: 'other',
			path: '/others',
			component: Others,
            meta: {
                peiqi: true,
                title: '其他'
            },
            // 独享路由守卫
            beforeEnter(to, from, next){
				to.meta.title = '佩奇!'
                next()
            }
		},
        // ... 略
	]
})
// ... 略
// 暴露路由器
export default router

2、Result

在这里插入图片描述


10、组件内路由守卫 beforeRouteEnter/beforeRouteLeave

  1. beforeRouteEnter:通过路由规则进入该组件时调用
  2. beforeRouteLeave:通过路由规则离开该组件时调用

需求:我想在进入 Others 时开启一个定时,离开时关闭定时

1、测试

<template>
	<h2>我是Others的内容</h2>
</template>

<script>
	export default {
		name:'Others',
		// 通过路由规则进入该组件时调用
		beforeRouteEnter (to, from, next) {
			console.log("=======>beforeRouteEnter\n", this)
			next()
		},
		// 通过路由规则离开该组件时调用
		beforeRouteLeave (to, from, next) {
			console.log("beforeRouteLeave=======>\n", this)
			next()
		}
	}
</script>

2、Result

在这里插入图片描述

3、分析一波

beforeRouteEnter 里 this 未定义,那该如何操作当 vc 呢?

没错就是在 next 回调,参数就是当前 vc 实例!

4、CODE

<template>
	<h2>我是Others的内容</h2>
</template>

<script>
	export default {
		name:'Others',
		data(){
			return {
				others: 555,
				timer: null
			}
		},
		// 通过路由规则进入该组件时调用
		beforeRouteEnter (to, from, next) {
			console.log("=======>beforeRouteEnter\n", this)
			next((instance)=>{
				// 参数 instance 就是当前 Others 组件实例,可以获取当前 vc 身上的一切!
				console.log('instance.others==>', instance.others)
				instance.timer = setInterval(()=>{
					console.log('Others 定时~')
				}, 100)
			})
		},
		// 通过路由规则离开该组件时调用
		beforeRouteLeave (to, from, next) {
			console.log("beforeRouteLeave=======>\n", this)
			clearInterval(this.timer)
			next()
		}
	}
</script>

5、Result

在这里插入图片描述


11、路由守卫总结

  1. 作用:对路由进行权限控制

  2. 分类:全局守卫、独享守卫、组件内守卫

  3. 全局守卫:

    //全局前置守卫:初始化时执行、每次路由切换前执行
    router.beforeEach((to,from,next)=>{
       console.log('beforeEach',to,from)
       if(to.meta.isAuth){ //判断当前路由是否需要进行权限控制
          if(sessionStorage.getItem('id')){ //权限控制的具体规则
             next() //放行
          }else{
             alert('暂无权限查看')
             // next({name:'guanyu'})
          }
       }else{
          next() //放行
       }
    })
    
    //全局后置守卫:初始化时执行、每次路由切换后执行
    router.afterEach((to,from)=>{
       console.log('afterEach',to,from)
       if(to.meta.title){ 
          document.title = to.meta.title //修改网页的title
       }else{
          document.title = 'vue_test'
       }
    })
    
  4. 独享守卫:

    beforeEnter(to,from,next){
       console.log('beforeEnter',to,from)
       if(to.meta.isAuth){ //判断当前路由是否需要进行权限控制
          if(localStorage.getItem('id')){
             next()
          }else{
             alert('暂无权限查看')
          }
       }else{
          next()
       }
    }
    
  5. 组件内守卫:

    //进入守卫:通过路由规则,进入该组件时被调用
    beforeRouteEnter (to, from, next) {
    },
    //离开守卫:通过路由规则,离开该组件时被调用
    beforeRouteLeave (to, from, next) {
    }
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

纯纯的小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值