VueRouter02 导航守卫
Vue Router导航守卫学习笔记。
vue-router提供了导航守卫,在路由跳转过程中来对导航进行处理,导航氛围三个级别:全局的、单个路由独享的、组件级的。
动态参数或者参数参数的改变并不会触发进入/离开的守卫,可以watch
监听$route
对象或者在beforeRouteUpdate
函数中进行处理
全局守卫
(1)全局前置守卫
router.beforeEach
注册全局前置守卫:
1 | const router = new VueRouter({ ... }) |
守卫是异步执行,导航跳转过程在所有守卫resolve之前一直处于等待中。
beforeEach
接受三个参数,第一个参数to
是将要进入的目标的路由对象,第二个参数from
是当前导航要离开的路由对象,第三个参数next
是一个函数,必须通过执行这个函数来确定导航的状态
1 | // 继续向下执行(执行钩子,如果钩子执行完毕确认导航) |
(2)全局解析守卫(V2.5.0)
router.beforeResolve
也可以注册全局守卫,与router.beforeEach
类似,区别是在导航被确认前,且组件内所有守卫和异步组件被解析后执行
1 | router.beforeResolve((to, from, next) => {}); |
(3)全局后置钩子
router.afterEach
是全局后置钩子,它不会接受next
函数,也不会改变导航本身
路由独享守卫
路由配置上定义beforeEnter
守卫:
1 | const router = new VueRouter({ |
它与全局守卫的参数一致,只是会在特定的路由起作用
组件内的守卫
组件内可以定义进入、离开、更新三中守卫
(1)进入
在组件内定义beforeRouterEnter
,会在导航被确认前调用,这时候组件实例还没有创建,所以不能获取到组件实例this
1 | const Foo = { |
可以为next
传一个回调来访问组件实例,在导航被确认时执行,这个回调的参数就是组件实例:
1 | beforeRouteEnter (to, from, next) { |
注意,beforeRouterEnter
是支持给next
传递回调的唯一的守卫。
(2)离开
在组件内定义beforeRouterLeave
,会在导航离开组件的对应路由前调用,可以访问组件实例this
1 | const Foo = { |
这个守卫一般用next(false)
来禁止在用户在还未保存修改前突然离开
(3)更新
在组件内定义beforeRouterUpdate
,在路由发生改变,组件被复用时会调用
例如动态路由/user/:id
的参数id
改变时,从/user/1
跳转到/user/2
时,会访问同一个组件,组件实例会被复用,此时其他导航守卫都不会被调用,只会触发beforeRouterUpdate
这个守卫
1 | const Foo = { |
导航解析流程
(1)路由间跳转
各种导航解析时,会先从组件离开导航开始执行,然后执行前置→解析→后置,而各种前置导航是从全局到局部的,全局→路由→组件
路由执行
next
后的顺序与Koa的中间件的原理类似,都是洋葱圈模型,一层层进入后直到afterEach
在按照原来的进入的相反顺序离开。
1 | // 组件离开 |
(2)路由动态参数变化,组件复用
当组件复用时,只会执行全局的前置、解析,以及组件本身的更新
1 | beforeEach start |
(3)总结
- 导航被触发
- 失活的组件里调用离开守卫
beforeRouteLeave
- 调用全局的前置守卫
beforeEach
- 在重用的组件里调用
beforeRouteUpdate
守卫(注意,只有重用组件才有这一步) - 在路由配置里调用路由独享守卫
beforeEnter
(注意,重用组件不会执行这一步) - 解析异步路由组件
- 在即将要进入的路由组件里调用
beforeRouteEnter
(注意,重用组件不会执行这一步) - 调用全局的解析守卫
beforeResolve
- 导航被确认
- 调用全局后置钩子
afterEach
- 触发DOM更新
- 用创建好的实例调用
beforeRouteEnter
守卫中传给next
的回调函数。