每个导航守卫都有三个参数:
-
to: Route
: 即将要进入的目标路由对象 -
from: Route
: 当前导航正要离开的路由 -
next: Function
: 必须调用该方法 resolve 这个钩子。执行效果依赖next
方法的调用参数-
next()
: 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。 -
next(false)
: 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到from
路由对应的地址。 -
next('/')
或者next({ path: '/' })
next({ name: 'Login' }) // 跳转到name为login的路由
跳转到一个不同的地址-当前的导航被中断,然后进行一个新的导航。你可以向
next
传递任意位置对象,且允许设置诸如replace: true
、name: 'home'
之类的选项以及任何用在router-link 的 to prop 或 router.push 中的选项。 -
next(error)
: 如果传入next
的参数是一个Error
实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。
-
1、全局前置守卫-router.beforeEach
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
next()
})
router.beforeEach在每个路由进入前都会被调用一次:常用来判断用户登录失效或者其他一些有时限、特殊操作(页面回滚到顶部、增加页面统一的标题等等)或者特殊页面的进入。
2、全局解析守卫-router.beforeResolve 2.5.0 新增
与router.beforeEach类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用--个人理解是跳转前最后执行的解析。
3、全局后置钩子-router.afterEach
router.afterEach((to, from) => {
// ...
})
并不是守卫,因为执行到的时候,路由应该已经跳转完成了。所以不会接受 next
函数也不会改变导航本身。
4、路由独享的守卫-beforeEnter
const router = new VueRouter({
routes: [
{
path: '/',
component: login,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
在单个路由上配置的参数,只针对该路由有效
5、组件内的守卫-beforeRouteEnter / beforeRouteUpdate / beforeRouteLeave
beforeRouteEnter: 在渲染该组件的对应路由被 confirm 前调用,无法获取this,这时即将登场的新组件还没被创建。
但是可以通过nuxt的回调进行实例方法的调用:
beforeRouteEnter (to, from, next) {
next(vm => {
// 通过 `vm` 访问组件实例
})
}
这是因为enter无法调用this所以才允许的,其他两个守卫并不支持。
beforeRouteLeave:离开当前组件的路由时调用,可以访问实例this。
beforeRouteLeave (to, from, next) {
next()
}
可以在一些页面中用来友好询问用户是否跳转,若取消跳转的话执行next(false)。
beforeRouteUpdate: 路由更新前调用,适用于一个组件被重复调用的情况(/xx?id)。
即页面上的路由是同一个,但是因为路由带参数,所以同一个组件会出现在不同页面中有不同的参数。
为了避免某些查询的数据混乱需要这个参数进行处理。
beforeRouteUpdate (to, from, next) {
console.log(this) // 这时this还是指向当前的组件,可以执行当前组件的方法
next() // confirm路由跳转
console.log(this) // 这时this还是已经指向新组件的实例this,可以进行新实例的操作
}
完整的导航解析流程
- 导航被触发。
- 在失活的组件里调用
beforeRouteLeave
守卫。 - 调用全局的
beforeEach
守卫。 - 在重用的组件里调用
beforeRouteUpdate
守卫 (2.2+)。 - 在路由配置里调用
beforeEnter
。 - 解析异步路由组件。
- 在被激活的组件里调用
beforeRouteEnter
。 - 调用全局的
beforeResolve
守卫 (2.5+)。 - 导航被确认。
- 调用全局的
afterEach
钩子。 - 触发 DOM 更新。
- 调用
beforeRouteEnter
守卫中传给next
的回调函数,创建好的组件实例会作为回调函数的参数传入。