一、导航守卫
经常在项目中,会对页面做一些权限控制,所以需要对路由变化做出处理,跳转或取消相应的路由。
导航:即路由发生变化。导航守卫即对路由变化做出处理。当然也分几种情况:对全局变化做处理、对“单个路由独享”变化做处理、对组件级(即具体的某个组件内部)变化做处理。
特别注意点:当参数或者查询发生变化的时候,并不会触发进入/离开的导航路由。这个可以参考上一篇博客的“响应路由参数的变化”,来监听$route对象或者使用beforeRouteUpdate
的组件内守卫。
(一)对全局变化做处理的守卫
1.全局前置守卫(route.beforeEach)
首先可以使用route.beforeEach()来注册一个全局前置守卫。
var router = new VueRouter({
...//
})
router.beforeEach((to,from,next) => {
})
下面解释下beforeEach方法的参数,之前在看Vue-router的时候,自己没有亲身实践过,对其中的参数含义理解模糊,果然还是需要实际操作才会记得住。
- to:这是即将要进入的某个路由对象
- from:指的是即将离开的某个路由对象
- next:这是必须的,因为如果没有它,那么路由会停滞在当前页面,不会往后执行并变化相应的路由。
next():指的是进入即将要进入的某个路由对象;next(false):指的是中断当前路由,重置回from的路由对象的url;next('/')或者next({path: '/'})指的是跳转至另一个想要进入的路由地址或者路由对象。
2.全局解析守卫(route.beforeResolve((to,from,next) => {}))
这是另一个类似于route.beforeEach的全局守卫方法。区别在于它会在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。
3.全局后置钩子(route.afterEach((to,from) => {}))
这个导航守卫的参数虽然没有next,指的是不会改变导航本身。进入路由之后调用。
(二)对“单个路由独享”变化做处理的守卫
1.可以直接在路由配置上定义beforeEnter守卫
const router = new VueRouter({
routes: [
{
path: 'foo',
component: Foo,
beforeEnter: (to,from,next) => {
...//
}
}
]
})
beforeEnter守卫的参数与beforeEach守卫的参数一致。
(三)对组件级变化做处理
面向于组件级,指的就是在组件内部使用的守卫方法,主要有beforeRouteEnter,beforeRouteUpdate,beforeRouteLeave三个方法。这三个方法的使用场景如下。
- beforeRouteEnter:顾名思义,在route进入之前进行调用,一般是对权限做控制。
- beforeRouteUpdate:指的是路由在变化的时候,既然是组件内部,那么就是针对于多个路由映射同一个组件的情况,就是params发生变化,例如/foo/1变化为/foo/2
- beforeRouteLeave:指的是离开某个路由之前,通常应用在禁止用户离开页面,或者用户在未保存时提示用户等。
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
}
注意:虽然beforeRouteEnter,不能访问实例this