导航守卫这个名字听起来略微有点中二(手动滑稽)
回归正题,导航守卫大体上分为以下三类:
1.全局守卫钩子
2.独享守卫钩子
3.路由组件守卫钩子
下面详细说明以上三种守卫钩子包含的方法及调用时序
1.全局守卫钩子
全局守卫顾名思义是在路由全局执行,即在路由切换时无差别的执行钩子(如果声明的话)
全局守卫钩子函数有三种
const router = new VueRouter({...});
//全局前置守卫
router.breforeEach((to, from, next) => {
//do something
})
//全局解析守卫
router.beforeResolve((to, from, next) => {
//do something
})
//全局后置守卫
router.afterEach((to, from) => {
//do something
})
to:route 即将进入的路由,to即路由对象,可访问to.name、to.path...具体参照我的另外一篇路由对象属性
from: route 即将离开的路由,即当前路由同样是路由对象
next:function 这个是必须要调用的,如果没有调用该方法那么接下来所有的钩子都不会被正常调用(页面不会渲染等),next()接受参数,根据参数的不同执行结果也不同
参数 | 说明 |
next() | 直接执行下一个钩子,如果执行完了导航状态为comfirmed |
next(false) | 中断当前导航,回到from的位置 |
next('/hello') 或 next({path: '/hello'}) next({name: 'hello'})以及可以设置router.push里的参数等 |
路由到任意地址,可以携带参数等 |
next(error) | 会回调到router.onError(callback),如果注册过该回调的话 |
2.独享守卫钩子
独享后卫钩子是定义在单独的某一个路由里的,因此是此路由单独触发定义的钩子与其他路由无关
const router = new VueRouter({
routes: [{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// do something
},
beforeLeave: (to, from, next) => {
//do something
}
}]
})
这里的参数与全局前置守卫钩子的参数使用相同
3.路由组件守卫钩子
请注意这里的路由组件四个字,区别于组件
即路由组件为在vue-router里注册的组件叫路由组件,而不存在vue-router里的组件(通俗例子就是如:一些可复用组件、弹窗组件、回到顶部组件等等)
这些钩子只能在路由组件里声明可用,在非路由组件里声明不会报错,但是也没有任何效果
<template>
<span>1111</span>
</template>
<script>
export default {
name: 'Hello',
props: ['name'],
mounted () {
//...
},
beforeRouteEnter (to, from, next) {
//这里!不!能!直接访问该组件的this实例
//此时路由导航还未被确认,组件还未实例化
//但是可通过在next的回调中访问,且只有该钩子支持接受回调参数
next(vm => {})
},
beforeRouteUpdate (to, from, next) {
//当前基础路由没有变化,但参数发生变化时使用
//如动态路由 /hello/:name,在/hello/smith 与 /hello/grace之间转跳
//由于使用的是同一hello组件,只是数据变化,因此该组件会被复用
//可以访问组件实例this,此时已是完整的组件
},
beforeRouteLeave (to, from, next) {
//离开该组件是使用
}
}
</script>
以上都必须使用next(),否则会导致组件无法正常进行渲染
4.完整的导航流程
1.导航被触发。
2.在失活的组件里调用离开守卫。
3.调用全局的 beforeEach 守卫。
4.在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
5.在路由配置里调用 beforeEnter。
6.解析异步路由组件。
7.在被激活的组件里调用 beforeRouteEnter。
8.调用全局的 beforeResolve 守卫 (2.5+)。
9.导航被确认。
10.调用全局的 afterEach 钩子。
11.触发 DOM 更新。
12.用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。
以上全部参考vue-router官方文档