在 Vue-router 中,导航钩子主要用于拦截导航过程,以实现跳转或取消等操作,具体分类如下:
-
全局前置守卫(router.beforeEach) :在路由跳转前触发,所有路由配置的组件都会触发该钩子。其接收三个参数:
to:代表要进入的目标路由对象。from:代表当前正要离开的路由对象。next:这是一个必须调用的方法,其执行效果依赖于传入的参数。如果不传参数,将执行下一个钩子函数;传入false,则中断当前导航,若浏览器的 URL 改变(可能是用户手动操作或浏览器后退按钮),则 URL 地址会重置到from路由对应的地址;传入'/'或{path: '/'}等路径,则跳转到对应的路由;传入error实例(2.4.0+),则导航会被终止,并将错误传递给router.onerror()注册过的回调。
-
全局解析守卫(router.beforeResolve) :2.5.0 新增。和全局前置守卫类似,也是在路由跳转前触发,但区别在于它在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后被调用。即在
beforeEach和组件内beforeRouteEnter之后,afterEach之前调用。同样接收to、from、next三个参数。 -
全局后置钩子(router.afterEach) :在路由跳转完成之后触发,接收
to、from两个参数,但没有next参数,也不会改变导航本身。 -
路由独享守卫(beforeEnter) :在单个路由配置时设置的钩子函数,仅在该路由下起作用。其参数与全局前置守卫相同,即
to、from、next。 -
组件内的守卫:直接在路由组件内部定义的钩子函数,类似于组件的生命周期钩子函数。按执行顺序包括:
-
beforeRouteEnter:在渲染该组件的对应路由被确认前调用。此阶段不能获取组件实例this,因为当守卫执行前,组件实例还没被创建。但可以通过传一个回调给next来访问组件实例,在导航被确认时执行回调,并将组件实例作为回调方法的参数。 -
beforeRouteUpdate(2.2 新增):在当前路由改变,但依然渲染该组件时调用。例如对于带有动态参数的路径/foo/:id,在/foo/1和/foo/2之间跳转时,由于会渲染同样的组件,组件实例会被复用,该钩子就会在这种情况下被调用。此时可以访问组件实例this。 -
beforeRouteLeave:导航离开该组件的对应路由时调用,可以访问组件实例this。常用于禁止用户在未保存修改前突然离开,可通过next(false)取消导航。
-
当发生路由跳转时(如从 a 路由跳转到 b 路由),完整的导航解析流程如下:
- 在 a 组件里调用离开守卫(
beforeRouteLeave)。 - 调用全局的
beforeEach守卫。 - 执行 b 路由配置里的
beforeEnter。 - 执行 b 组件的进入守卫(
beforeRouteEnter)。 - 调用全局的
beforeResolve守卫(2.5+)。 - 导航被确认。
- 调用全局的
afterEach钩子。 - 触发 DOM 更新。
- 调用
beforeRouteEnter守卫中传给next的回调函数,创建好的组件实例会作为回调函数的参数传入。