红藕香残玉簟秋,轻解罗裳,独上兰舟。云中谁寄锦书来?
导航守卫
- vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。
全局前置守卫(router.beforeEach)
1 | const router = createRouter({ ... }) |
当一个导航触发的时候,全局前置导航守卫按照顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于等待中。
全局前置守卫参数
参数 | 描述 |
---|---|
to | 即将要进入的目标的路由对象 |
from | 当前导航正要离开的路由 |
next (可选) | 用该方法来 resolve 这个钩子,执行效果依赖 next 方法的调用参数 |
- to:Route 即将要进入的目标的路由对象
- from:Route 当前导航正要离开的路由
- next:Function 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数
- next不同参数执行效果
- next() 进行管道的下一个钩子函数,如果所有钩子执行完,则导航状态就是 confirmed(确认的)。
- next(false) 中断当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 会重置到 from 路由对应的地址
- next(‘/‘)或者 next({path:’/‘}) 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。
- next(error) 如果传入 next 的参数是一个 Error 实例,则导航会被终止,且该错误会传递给 router.onError()注册过的回调。
- 确保要调用 next 方法,否则钩子就不会被 resolved
1 | router.beforeEach((to, from, next) => { |
全局解析守卫 (router.beforeResolve )
- 每次导航时都会触发,但是确保在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被正确调用。
1 | router.beforeResolve(async to => { |
路由导航守卫(beforeEnter)
- 直接在路由配置上定义 beforeEnter 守卫,只在进入路由时触发,不会在 params、query 或 hash 改变时触发。
1 | const router = new VueRouter({ |
组件内的导航守卫(beforeRouteEnter,beforeRouteUpdate,beforeRouteLeave)
- 路由组件内直接定义路由导航守卫(传递给路由配置的)
1 | const Foo = { |
- beforeRouteEnter 守卫 不能 访问 this,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。
- 不过,你可以通过传一个回调给 next 来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。
1 | beforeRouteEnter (to, from, next) { |
- 注意 beforeRouteEnter 是支持给 next 传递回调的唯一守卫。对于 beforeRouteUpdate 和 beforeRouteLeave 来说,this 已经可用了,所以不支持传递回调,因为没有必要了。
1 | beforeRouteUpdate (to, from, next) { |
- 这个离开守卫通常用来禁止用户在还未保存修改前突然离开。该导航可以通过 next(false) 来取消。
1 | beforeRouteLeave (to, from , next) { |
完整的导航解析流程
- 导航被触发。
- 在失活的组件里调用 beforeRouteLeave 守卫。
- 调用全局的 beforeEach 守卫。
- 在重用的组件里调用 beforeRouteUpdate 守卫。
- 在路由配置里调用 beforeEnter。
- 解析异步路由组件。
- 在被激活的组件里调用 beforeRouteEnter。
- 调用全局的 beforeResolve 守卫。
- 导航被确认。
- 调用全局的 afterEach 钩子。
- 触发 DOM 更新。
- 调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。