详解vue-router 中的导航钩子

vue-router 的导航钩子,主要做用是拦截导航,让他完成跳转或取消。javascript

有三种方式能够植入路由导航过程当中:vue

  • 全局的
  • 单个路由独享的
  • 组件级的

1. 全局导航钩子:java

   全局导航钩子主要有两种钩子:前置守卫、后置钩子, 注册一个全局前置守卫:vue-router

const router = new VueRouter({ ... });
router.beforeEach((to, from, next) => {
    // do someting
});
router.afterEach((to, from) => {
    // do someting
});

这三个参数 to 、from 、next 分别的做用:异步

   to: Route,表明要进入的目标,它是一个路由对象函数

  from: Route,表明当前正要离开的路由,一样也是一个路由对象this

  next: Function,这是一个必须须要调用的方法,而具体的执行效果则依赖 next 方法调用的参数spa

   next():进入管道中的下一个钩子,若是所有的钩子执行完了,则导航的状态就是 confirmed(确认的)code

   next(false):这表明中断掉当前的导航,即 to 表明的路由对象不会进入,被中断,此时该表 URL 地址会被重置到 from 路由对应的地址component

  next(‘/’) 和 next({path: ‘/’}):在中断掉当前导航的同时,跳转到一个不一样的地址

   next(error):若是传入参数是一个 Error 实例,那么导航被终止的同时会将错误传递给 router.onError() 注册过的回调

  注意:next 方法必需要调用,不然钩子函数没法 resolved,不一样于前置守卫,后置钩子并无 next 函数,也不会改变导航自己。

 2. 路由独享的钩子

  顾名思义,即单个路由独享的导航钩子,它是在路由配置上直接进行定义的: beforeEnter

 1 cont router = new VueRouter({
 2     routes: [
 3         {
 4             path: '/file',
 5             component: File,
 6             beforeEnter: (to, from ,next) => {
 7                 // do someting
 8             }
 9         }
10     ]
11 });
12 // 至于他的参数的使用,和全局前置守卫是同样的

 3. 组件内的导航钩子 组件内的导航钩子主要有这三种:

beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave。他们是直接在路由组件内部直接进行定义的:

 1 const File = {
 2     template: `<div>This is file</div>`,
 3     beforeRouteEnter(to, from, next) {
 4         // do someting
 5         // 在渲染该组件的对应路由被 confirm 前调用
 6     },
 7     beforeRouteUpdate(to, from, next) {
 8         // do someting
 9         // 在当前路由改变,可是依然渲染该组件是调用
10     },
11     beforeRouteLeave(to, from ,next) {
12         // do someting
13         // 导航离开该组件的对应路由时被调用
14     }
15 }

须要注意是: beforeRouteEnter 不能获取组件实例 this,由于当守卫执行前,组件实例被没有被建立出来,剩下两个钩子则能够正常获取组件实例 this 可是并不意味着在 beforeRouteEnter 中没法访问组件实例,咱们能够经过给 next 传入一个回调来访问组件实例。在导航被确认是,会执行这个回调,这时就能够访问组件实例了,如:

1 beforeRouteEnter(to, from, next) {
2     next (vm => {
3         // 这里经过 vm 来访问组件实例解决了没有 this 的问题
4     })
5 }

 注意,仅仅是 beforRouteEnter 支持给 next 传递回调,其余两个并不支持。由于归根结底,支持回调是为了解决 this 问题,而其余两个钩子的 this 能够正确访问到组件实例,全部没有必要使用回调

 最后是完整的导航解析流程:

  1. 导航被触发
  2. 在失活的组件里调用离开守卫
  3. 调用全局的 beforeEach 守卫
  4. 在重用的组件里调用 beforeRouteUpdate 守卫
  5. 在路由配置里调用 beforEnter
  6. 解析异步路由组件
  7. 在被激活的组件里调用 beforeRouteEnter
  8. 调用全局的 beforeResolve 守卫
  9. 导航被确认
  10. 调用全局的 afterEach 钩子
  11. 触发 DOM 更新
  12. 在建立好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数
相关文章
相关标签/搜索