今天根据vue-router官网,重新系统的学习了导航守卫
全局/路由独享守卫/组件内
1.全局前置守卫
注册方式:
router.beforeEach((to,from,next)=>{
})
参数:
to:即将进入的目标路由
from:当前导航正要离开的路由
next:是一个function,一定要调用此方法来resolve这个钩子。
next调用方式:
1) next() 进行下一个钩子
2) next(false) 中断当前导航,阻止进入
3) next(’/’)或者next({path:’/’}) 进入一个不同于to的地址
4) next(error) 如果传入error实例,导航被终止且传入router.onError
2.全局解析守卫
注册方式:
router.beforeResolve((to,from,next)=>{
})
全局解析守卫和全局前置守卫类似,区别是在导航被确认之前
,同时在所有组件内守卫和异步路由组件被解析之后
,解析守卫就被调用
3.全局后置钩子
注册方式:
router.afterEach((to,from)=>{
})
全局后置钩子和守卫不同的是,钩子不会接受next函数,也不会改变导航本身
4.路由独享守卫
注册方式
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
在路由配置上直接定义beforeEnter守卫
5.组件内的守卫
-
beforeRouteEnter(不能访问this)
渲染该组件对应路由之前被调用,不能访问this,因为此守卫执行前,组件实例未被创建
如何解决此时无法访问this的问题?
答案:传一个回调给next
beforeRouteEnter((to,from,next)=>{ next(vm=>{ 此时vm=this,通过vm访问组件实例 } })
-
beforeRouteUpdate(可以访问this)
调用时间:当前路由改变,但是该组件被复用时。
例如:动态参数路由,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
-
brforeRouteLeave(可以访问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) } }
1)组件内的三个守卫中,只有beforeRouteEnter可以向next函数传回调,另外两个由于已经可以访问组件实例this,没必要也不支持传递回调
2)组件内的守卫,必须是路由组件!!!在路由里注册的路由组件才可以使用,否则无法使用(父组件是路由组件,调用子组件,子组件不是路由组件,无法使用以上三个组件内的守卫)
6.导航解析流程
- 导航被触发。
- 在失活的组件里调用
beforeRouteLeave
守卫。 - 调用全局的
beforeEach
守卫。 - 在重用的组件里调用
beforeRouteUpdate
守卫 (2.2+)。 - 在路由配置里调用
beforeEnter
。 - 解析异步路由组件。
- 在被激活的组件里调用
beforeRouteEnter
。 - 调用全局的
beforeResolve
守卫 (2.5+)。 - 导航被确认。
- 调用全局的
afterEach
钩子。 - 触发 DOM 更新。
- 用创建好的实例调用
beforeRouteEnter
守卫中传给next
的回调函数。