导航守卫:
表示路由正在发生改变( 路由导航分为:全局的, 单个路由独享的, 或者组件级的 )
通过观察 $route 对象来应对这些变化,或使用 beforeRouteUpdate 的组件内路由钩子
每个守卫方法接收三个参数:
to: 要进入的目标路由对象
from: 要离开的路由
next(): 调用该方法 resolve 。执行效果依赖 next 方法的调用参数。
如果不调用 next 钩子不会 resolved,导航可以通过 next(false) 取消
全局守卫
router.beforeEach(): 当导航触发时,全局前置守卫按照创建顺序调用
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {})
全局后置钩子
router.afterEach(): 不会接受 next 函数也不会改变导航本身
router.afterEach((to, from) => {})
路由routes选项中钩子
beforeEnter(): 在路由配置上直接定义 beforeEnter
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {}
}
]
})
组件内路由钩子
beforeRouteEnter(): 不能获取组件实例 this, 因为组件实例还没被创建
beforeRouteEnter (to, from, next) {
next( vm => { /* vm: 组件实例作为回调方法的参数 */
console.log( vm ); /* 通过 `vm` 访问组件实例 */
})
}
beforeRouteUpdate():
组件被复用时调用,可以访问组件实例 this (动态参数路径/foo/:id,在 /foo/1 和 /foo/2 跳转时)
beforeRouteUpdate (to, from, next) {
// just use `this`
this.name = to.params.name
next()
}
beforeRouteLeave(): 导航离开该组件的对应路由时调用,可以访问组件实例 this
beforeRouteLeave (to, from , next) {
const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
if (answer) {
next()
} else {
next(false)
}
}
const Foo = {
template: `...`,
beforeEnter(to, from, next),
beforeRouteEnter(to, from, next){},
beforeRouteLeave (to, from, next) {}
}
完整的导航解析流程
导航被触发。
在失活的组件里调用离开守卫
调用全局的 beforeEach 守卫
在重用的组件里调用 beforeRouteUpdate 守卫
在路由配置里调用 beforeEnter
解析异步路由组件
在被激活的组件里调用 beforeRouteEnter
调用全局的 beforeResolve 守卫
导航被确认
调用全局的 afterEach 钩子
触发 DOM 更新
用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数