vue导航守卫(钩子函数)
vue-router有哪几种导航钩子( 导航守卫 )?
面试的时候,面试官会经常问这个问题。
- 全局:
beforeEach((to, from, next) => {调用next来resolve这个钩子} ),
beforeResolve((to, from, next) => {} ),
afterEach((to, from) => {} ) - 路由独享:
beforeEnter((to, from, next) => {} ), - 组件内部:
beforeRouteEnter((to, from, next) => {next可以传回调,回调里面可以用vm访问实例} ), 内部没有this,因为路由还没confirm
beforeRouteUpdate((to, from, next) => {}),可以拿到this
beforeRouteLeave((to, from, next) => {})
1.全局守卫
通常我们在开发项目的时候会通过 router.beforeEach 注册一个全局前置守卫:
const router = new VueRouter({ ... }) router.beforeEach((to, from, next) => { // ... })
每个守卫有三个参数:
to:Route: 即将要进入的目标 路由对象
from:Route:当前导航正要离开的路由
next:Function:一定要调用该方法来 resolve 这个钩子。执行效果依赖 next方法的调用参数。
-
next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。 -
next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到from路由对应的地址。 -
next('/')或者next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向next传递任意位置对象,且允许设置诸如replace: true、name: 'home'之类的选项以及任何用在router-link的toprop 或router.push中的选项。 -
next(error): (2.4.0+) 如果传入next的参数是一个Error实例,则导航会被终止且该错误会被传递给router.onError()注册过的回调。
注意:确保 next 函数在任何给定的导航守卫中都被严格调用一次。它可以出现多于一次,但是只能在所有的逻辑路径都不重叠的情况下,否则钩子永远都不会被解析或报错。
在全局守卫里面可以对token或者cookie登录做判断校验。
router.beforeEach((to, from, next) => { // 如果有token 说明该用户已登陆 if (localStorage.getItem('token')) { // 在已登陆的情况下访问登陆页会重定向到首页 if (to.path === '/login') { next({path: '/'}) } else { next({path: to.path || '/'}) } } else { // 没有登陆则访问任何页面都重定向到登陆页 if (to.path === '/login') { next() } else { next(`/login?redirect=${to.path}`) } } })
2.路由守卫
顾名思义,就是在路由配置上直接定义 beforeEnter 守卫:
const router = new VueRouter({ routes: [ { path: '/foo', component: Foo, beforeEnter: (to, from, next) => { // ... } } ] })
路由守卫与全局前置守卫的方法参数是一样的。实际开发过程中本人用到的相对少一些。
3.组件守卫
此守卫是在路由组件内直接定义以下路由导航守卫:
beforeRouteEnterbeforeRouteUpdate(2.2 新增)beforeRouteLeave
const Foo = { template: `...`, beforeRouteEnter (to, from, next) { // 在渲染该组件的对应路由被 confirm 前调用 // 不!能!获取组件实例 `this` // 因为当守卫执行前,组件实例还没被创建 }, beforeRouteUpdate (to, from, next) { // 在当前路由改变,但是该组件被复用时调用 // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候, // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。 // 可以访问组件实例 `this` }, beforeRouteLeave (to, from, next) { // 导航离开该组件的对应路由时调用 // 可以访问组件实例 `this` } }
在开发过程中,一般会与keep-alive结合用的比较多。
完整的导航解析流程
- 导航被触发。
- 在失活的组件里调用
beforeRouteLeave守卫。 - 调用全局的
beforeEach守卫。 - 在重用的组件里调用
beforeRouteUpdate守卫 (2.2+)。 - 在路由配置里调用
beforeEnter。 - 解析异步路由组件。
- 在被激活的组件里调用
beforeRouteEnter。 - 调用全局的
beforeResolve守卫 (2.5+)。 - 导航被确认。
- 调用全局的
afterEach钩子。 - 触发 DOM 更新。
- 调用
beforeRouteEnter守卫中传给next的回调函数,创建好的组件实例会作为回调函数的参数传入。

浙公网安备 33010602011771号