概念:
路由的导航守卫 又叫做路由的钩子函数(生命周期函数)
其它其它的八个生命周期是Vue实例的生命周期,还有两个是缓存的生命周期
作用(场景):
在跳转之前页面之处做相应的处理,例如鉴权,登录才能进去
使用:
有 全局、单个路由独享、组件级 三种使用方式
组件级的导航守卫很少用,不好维护
1. 全局
(1)路由前置守卫
const router = new VueRouter({ ... })
router.beforeEach((to,from,next)=>{
if(true){
//继续执行
next();
}else{
//跳转到其它页面
router.push('/login');
// 或者这么写next('/login')
}
})
看个实例:
有这么一个界面
我们想控制他们进入界面前的行为,可以这么做:
将next设置为了false,代表不允许进到to路由,就会发现原来的内容已经进不去。
(2)全局解析守卫
你可以用 router.beforeResolve 注册一个全局守卫。这和 router.beforeEach 类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。
(3)全局后置钩子
你也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身:
router.afterEach((to, from) => {
// ...
})
2. 路由独享
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
实例
有user路由显示的界面如下
我们想要单独控制某个路由可以,可以使用组件路由,有如下代码
如下发现页面看不到了(这里url已经输入了/user,是自己回退到home页面)
3. 组件内
最后,你可以在路由组件内直接定义以下路由导航守卫:
- beforeRouteEnter
- beforeRouteUpdate (2.2 新增)
- beforeRouteLeave
const Foo = {
template: `...`,
beforeRouteEnter(to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate(to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave(to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
}
下面看两个实例对组件内的路由导航守卫有更清晰的认识:
- beforeRouteEnter实例
这个直接写代码
有如下界面,会发现一样失败,会打回到home (但是呢,这个推荐使用路由级的导航守卫)
- beforeRouteLeave 实例
页面如下
代码如下
意思是当data中的属性为true才能马上离开,否则会有一个弹窗确认之后才能离开,cancel不能离开。
直接看data属性不为true的情况,发现有弹窗
点击cancel回到当前页面
总结
vue一共为我们提供了三种路由守卫
(1)全局守卫
- beforeEach 路由进入之前
- beforeResolve (即在 beforeEach 和 组件内beforeRouteEnter 之后,afterEach之前调用。)这个几乎不用
- afterEach 路由进入之后
(2)组件内置守卫
- beforeRouteEnter 路由进入之前
- beforeRouteUpdate 路由更新之前
- beforeRouteLeave 路由离开之前
(3)路由独享守卫
- beforeEnter 路由进入之前
问答
(1) beforEach 和 beforeResolve 的区别
都是在路由跳转之前执行 但是 beforeEach 是在解析路由规则之前 执行 beforeResolve 是解析之后 路由跳转之前执行 beforeEach 比 beforeResolve 执行的时机更早
(2) 路由守卫的执行顺序
全局前置 独享守卫 组件守卫(beforeRouteEnter) 解析守卫 后置守卫