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的回调函数。