有的时候,我们需要通过路由来进行一些操作,比如最常见的登录权限验证,当用户满足条件时,才让其进入导航,否则就取消跳转,并跳到登录页面让其登录。
为此我们有很多种方法可以植入路由的导航过程:全局的, 单个路由独享的, 或者组件级的。
全局守卫
vue-router全局有三个守卫:
- router.beforeEach 全局前置守卫 进入路由之前
- router.beforeResolve 全局解析守卫(2.5.0+) 在beforeRouteEnter调用之后调用
- router.afterEach 全局后置钩子 进入路由之后
进入新的页面 beforeEach //先执行
进入路由的配置当中 beforeEnter//第二个执行
组件进入时的钩子beforeRouteEnter//第三个执行
组件离开时的钩子beforeRouteLeave
解析完成beforeResolve
当前进入完毕 afterEach
组件渲染完毕 会调用 beforeRouteEnter的回调函数
// main.js 入口文件import router from './router'; // 引入路由router.beforeEach((to, from, next) => { next();});router.beforeResolve((to, from, next) => { next();});router.afterEach((to, from) => { console.log('afterEach 全局后置钩子');});to,from,next 这三个参数:
to和from是将要进入和将要离开的路由对象,路由对象指的是平时通过this.$route获取到的路由对象。
- next:Function 这个参数是个函数,且必须调用,否则不能进入路由(页面空白)。
- next() 进入该路由。
- next(false): 取消进入路由,url地址重置为from路由地址(也就是将要离开的路由地址)。
- next 跳转新路由,当前的导航被中断,重新开始一个新的导航。
我们可以这样跳转:next('path地址')或者next({path:''})或者next({name:''})
且允许设置诸如 replace: true、name: 'home' 之类的选项
以及你用在router-link或router.push的对象选项。
路由独享守卫:
如果你不想全局配置守卫的话,你可以为某些路由单独配置守卫:
const router = new VueRouter({ routes: [ { path: '/foo', component: Foo, beforeEnter: (to, from, next) => { // 参数用法什么的都一样,调用顺序在全局前置守卫后面,所以不会被全局守卫覆盖 // ... } } ]})路由组件内的守卫:
- beforeRouteEnter 进入路由前
- beforeRouteUpdate (2.2) 路由复用同一个组件时
- beforeRouteLeave 离开当前路由时
文档中的介绍:
beforeRouteEnter (to, from, next) {// 在路由独享守卫后调用 不!能!获取组件实例 `this`,组件实例还没被创建}, beforeRouteEnter(to,from,next){ console.log(from)
console.log(this)
if(from.path === '/'){
console.log('home')
}
组件渲染完毕,会调用beforeRouteEnter的回调函数
next((vm)=>{
console.log(vm)
});
},
beforeRouteUpdate (to, from, next) {// 在当前路由改变,但是该组件被复用时调用 可以访问组件实例 `this`// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。},beforeRouteLeave (to, from, next) {// 导航离开该组件的对应路由时调用,可以访问组件实例 `this`//确认组件离开代码:
export default {
beforeRouteLeave(to,from,next){
console.log('todo leave');
if (global.confirm('are you sure')){
next();
}
},
}