概念
导航发生变化时,导航钩子主要用来拦截导航,让它完成跳转或取消
记住参数或查询的改变并不会触发进入/离开的导航守卫。你可以通过观察
$route
对象来应对这些变化,或使用beforeRouteUpdate
的组件内守卫。
全局的
前置守卫 router.beforeEach
使用场景 - 未登录去下单,跳转到登录页
// main.js
// 在进入路由之前 每一次都会执行此方法 全局钩子 路由拦截
router.beforeEach(function(to,from,next){ //to:将要去的页面 from:离开的页面
if(to.path==='/list'){
next({path:'/add'}) //跳到add页面
}else{
next();
}
})
后置钩子router.afterEach
使用场景 - 改变浏览器title
router.afterEach((to, from) => {
document.title=to.meta.title;
})
//不会改变导航本身
单个路由独享的
beforeEnter
与全局前置守卫
router.beforeEach
的方法参数是一样的
//在路由配置上直接定义 beforeEnter 守卫
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
if(to.path==='/list'){
next({path:'/add'}) //跳到add页面
}else{
next();
}
}
}
]
})
组件级的
进入组件前beforeRouteEnter
使用场景 - 进入这个组件前你要做什么初始化操作
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
next(vm => {
// 通过 `vm` 访问组件实例
})
},
}
//参数同beforeEach
组件更新或改变时beforeRouteUpdate
使用场景 - 复用组件时(对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候)
const Foo = {
template: `...`,
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
this.name = to.params.name
next()
},
}
//参数同beforeEach
离开组件时beforeRouteLeave
使用场景
1.清除定时器
2.用户在还未保存修改前突然离开提示等等
const Foo = {
template: `...`,
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
if (answer) {
next()
} else {
next(false)
}
}
}
//参数同beforeEach
完整的导航解析流程
- 导航被触发。
- 在失活的组件里调用离开守卫
beforeRouteLeave
。 - 调用全局的
beforeEach
守卫。 - 在重用的组件里调用
beforeRouteUpdate
守卫 (2.2+)。 - 在路由配置里调用
beforeEnter
。 - 解析异步路由组件。
- 在被激活的组件里调用
beforeRouteEnter
。 - 调用全局的
beforeResolve
守卫 (2.5+)。 - 导航被确认。
- 调用全局的
afterEach
钩子。 - 触发 DOM 更新。
- 用创建好的实例调用
beforeRouteEnter
守卫中传给next
的回调函数。
网友评论