1, 什么是路由守卫?
路由守卫也叫路由钩子函数, 它是在路由跳转过程中调用的函数, 通过路由守卫可获取路由信息和阻止路由跳转
2, 有哪些路由守卫?
路由守卫有以下三种:
组件内的路由守卫: beforeRouteEnter() beforeRouterUpdate() beforeRouteLeave()
全局路由守卫: beforeEach() afterEach()
单个路由守卫: beforeEnter()
3, 路由守卫有哪些参数, 作用是什么?
路由守卫的参数有三个: to, from , next
to: 表示路由跳转的目标信息对象 (到哪儿去)
from: 表示路由跳转的来源信息对象(从哪儿来)
next: 回调函数, 表示是否允许路由跳转, 调用允许, 不调用则禁止
4, 什么时候用路由守卫?
beforeRouteEnter, beforeEnter, beforeEach, 这三个都是路由进入之前的守卫, 这些路由守卫常用于做登录认证, 在这里判断用户是否已经登录, 如果已经登录,调用next()允许进入, 如果没有登录, 不调用next(),禁止进入 主要针对一些需要登录状态才能访问的页面, 如: 个人信息页
beforeRouteLeave 是路由离开之前的守卫, 在一些表单页面, 在这个函数中提示, 离开页面, 填写的表单信息会丢失 如: 在线测试页面, 测试提交之前, 不允许离开这一页
beforeRouteUpdate 是路由更新时调用的钩子函数, 当路由路径来源和目标相同(当前页跳转当前页),并且参数不同时, 会调用这个钩子, 常用于搜索页, 当搜索关键字改变时, 在这里更新数据
5, 使用路由守卫需要注意哪些问题?
(1) 由于在任何组件中都能使用this.$router, 所以全局路由守卫可以在任意组件中调用
(2) beforeRouteEnter路由进入之前,组件还未创建,打印this是undefined, 如果想用组件对象,可以在next()的回调中拿到组件对象 next( vm=>{ console.log(vm) })
(3) this.$router 是/src/router/index.js中创建的路由对象, 全局唯一, 用于编程式导航跳转和全局路由守卫
this.$route 是路由跳转的信息对象, 每一个路由对应一个$route对象, 用于路由传值和路由监听
(4) 路由监听和路由守卫的区别:
路由监听: 在组件中watch字段中监听$route, 实现路由监听, 只能监听路由变化, 不能修改路由和限制路由跳转
路由守卫: 使用路由钩子函数实现守卫, 路由守卫不止可以监听路由, 还能控制路由跳转
(5) 当路由跳转时, 跳转的路径和参数与当前完全一致, 没有变化, 不会调用路由钩子函数, 会报错NavigationDuplicated: Avoided redundant navigation to current location: "/about?page=5".
解决方案如下: 在/src/router/index.js中添加如下代码: 原理是捕获push函数报错, 不抛出错误
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => {
//throw(err) // 抛出错误,控制台会显示错误信息, 如果不抛出,控制台不会报错
return err;
})
}