在开发过程经常会遇到譬如在没有登录时点击页面内容,提醒用户登录,跳转到登录页面的需求等等;vue提供了导航守卫主要用来通过跳转或者取消的方式守卫导航。
首先看一下完整的导航解析流程
1、导航被触发。
2、在失活的组件里调用离开守卫(beforeRouteLeave)。
3、调用全局守卫(beforeEach )。
4、在重用的组件里调用更新守卫( beforeRouteUpdate) (2.2+)。
5、在路由配置里调用 beforeEnter。
6、解析异步路由组件。
7、在被激活的组件里调用组件内守卫beforeRouteEnter。
8、调用全局的 beforeResolve 守卫 (2.5+)。
9、导航被确认。
10、调用全局的 afterEach 钩子。
11、触发 DOM 更新。
12、用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。
下面介绍一下全局守卫、路由独享守卫和组件内守卫。
1、全局守卫:
router.beforeEach((to,from,next) => {})
to、from、next三个参数如下
router.beforeEach((to,from,next) => {
// to,from,next 3个参数
// to: Route, 即将要进入的路由对象
// from: Route, 当前导航将要离开的路由对象
// next: Function, 切记要调用该函数来resolve这个钩子,里面可以写自己想要的参数
// 1、next(): 进行管道中的下一个钩子函数,如果全部钩子函数执行完,导航的状态就说明确认了
// 2、next(false): 中断当前导航,重置到from路由对应的地址
// 3、next('/drinks'): 或者next({path:'/drinks'}): 当前导航被中断,跳转到指定的路由
// 4、next(error): 如果传入参数是Error的实例,导航会被终止且该错误会被传递给router.onError()注册过的回调
// 这里可以写逻辑判断,比如没有登录,点击某个tab就跳转到登录页面
if (to.path == '/food') {
alert('还没登录,请先登录');
next('/drinks');
} else {
next();
}
})
2、全局后置钩子
// 全局后置钩子
router.afterEach((to,from) => {
// to from 2个参数 和守卫相比少了next参数,因此不能改变导航本身
// to: Route, 即将要进入的路由对象
// from: Route, 当前导航将要离开的路由对象
// alert('确定要离开吗?')
})
3、路由独享守卫
// 在路由配置上直接定义 beforeEnter 守卫:
const routes = [
{
path: '/drinks',
name: 'Drinks',
component: Drinks,
// 路由独享守卫 参数含义和全局守卫一样
beforeEnter:(to, from,next) =>{
alert('drinks')
next()
}
},
{
path: '/fruits',
name: 'Fruits',
component: Fruits,
redirect: '/fruits/apple', // 设置默认展示 Apple
children:[ //二级路由
{
path: '/fruits/apple',
name: 'Apple',
component: Apple
}
]
},
{ // 当路由导航地址错误时默认跳转路径
path:'*',
redirect: '/'
}
]
3、组件内守卫
// 组件内守卫
// 进入
beforeRouteEnter:(to,from,next) => {
// alert('hello world ' + this.name) 注意:这里不能获取组件实例 `this`,可以通过传一个回调给 next来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数
next(vm => {
alert('hello world ' + vm.name)
next()
})
},
// 更新 (2.2 新增)
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
alert('hello world ' + this.name)
},
// 离开 这个离开守卫通常用来禁止用户在还未保存修改前突然离开。该导航可以通过 next(false) 来取消。
beforeRouteLeave(to,from,next){
// 可以访问组件实例 `this`
if (confirm('确定离开吗?') == true) {
next()
} else {
next(false)
}
}