Vue-router 中导航钩子

73 阅读3分钟

在 Vue-router 中,导航钩子主要用于拦截导航过程,以实现跳转或取消等操作,具体分类如下:

  1. 全局前置守卫(router.beforeEach) :在路由跳转前触发,所有路由配置的组件都会触发该钩子。其接收三个参数:

    • to:代表要进入的目标路由对象。
    • from:代表当前正要离开的路由对象。
    • next:这是一个必须调用的方法,其执行效果依赖于传入的参数。如果不传参数,将执行下一个钩子函数;传入false,则中断当前导航,若浏览器的 URL 改变(可能是用户手动操作或浏览器后退按钮),则 URL 地址会重置到from路由对应的地址;传入'/'{path: '/'}等路径,则跳转到对应的路由;传入error实例(2.4.0+),则导航会被终止,并将错误传递给router.onerror()注册过的回调。
  2. 全局解析守卫(router.beforeResolve) :2.5.0 新增。和全局前置守卫类似,也是在路由跳转前触发,但区别在于它在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后被调用。即在beforeEach和组件内beforeRouteEnter之后,afterEach之前调用。同样接收tofromnext三个参数。

  3. 全局后置钩子(router.afterEach) :在路由跳转完成之后触发,接收tofrom两个参数,但没有next参数,也不会改变导航本身。

  4. 路由独享守卫(beforeEnter) :在单个路由配置时设置的钩子函数,仅在该路由下起作用。其参数与全局前置守卫相同,即tofromnext

  5. 组件内的守卫:直接在路由组件内部定义的钩子函数,类似于组件的生命周期钩子函数。按执行顺序包括:

    • beforeRouteEnter:在渲染该组件的对应路由被确认前调用。此阶段不能获取组件实例this,因为当守卫执行前,组件实例还没被创建。但可以通过传一个回调给next来访问组件实例,在导航被确认时执行回调,并将组件实例作为回调方法的参数。

    • beforeRouteUpdate(2.2 新增):在当前路由改变,但依然渲染该组件时调用。例如对于带有动态参数的路径/foo/:id,在/foo/1/foo/2之间跳转时,由于会渲染同样的组件,组件实例会被复用,该钩子就会在这种情况下被调用。此时可以访问组件实例this

    • beforeRouteLeave:导航离开该组件的对应路由时调用,可以访问组件实例this。常用于禁止用户在未保存修改前突然离开,可通过next(false)取消导航。

当发生路由跳转时(如从 a 路由跳转到 b 路由),完整的导航解析流程如下:

  1. 在 a 组件里调用离开守卫(beforeRouteLeave)。
  2. 调用全局的beforeEach守卫。
  3. 执行 b 路由配置里的beforeEnter
  4. 执行 b 组件的进入守卫(beforeRouteEnter)。
  5. 调用全局的beforeResolve守卫(2.5+)。
  6. 导航被确认。
  7. 调用全局的afterEach钩子。
  8. 触发 DOM 更新。
  9. 调用beforeRouteEnter守卫中传给next的回调函数,创建好的组件实例会作为回调函数的参数传入。