Vue中管理路由-vue-router路由守卫
在Vue项目中,路由跳转前经常要做一些验证,如登录验证,权限验证等,是应用中的普遍需求,可以通过导航守卫来实现。导航守卫也叫路由守卫,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。
路由生命周期
和组件一样,路由也有生命周期,生命周期的钩子函数称为路由守卫。
vue-router提供的路由守卫通过跳转或取消的方式守卫导航,守卫的应用场景有全局守卫、路由独享的守卫 、组件内的守卫。
路由守卫构造函数通常有3个参数:
1、to 路由对象,要进入的目标路由对象
2、from 路由对象 ,要离开的路由对象
3、next 函数, 用于结束当前钩子
一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数
。
next()
无参数表示进入下一个生命周期,如果所有的 钩子函数都执行完了(生命周期/守卫),则导航状态就是confirmed(确认的)next(false)
中断当前导航,重置到 from 路由对应的地址。next(’/xx’) 或者 next({path:’/xxx’})
中断当前的导航, 进行一个新的导航,跳转到一个指定的 地址。
全局守卫
全局钩子函数在定义全局路由时使用,通常用路由实例的原型上有两个钩子:beforeEach
和afterEach
,用beforeEach钩子来实现全局前置守卫。
const router = new VueRouter({ ... })
/*前置全局守卫,路由跳转之前执行,参数to,from,next * to:Route 要进入的目标路由对象 * from:Route 要离开的路由对象 * next:Function 决定跳转或取消导航,next函数指定下一步操作,从而结束这个钩子 * */
router.beforeEach((to, from, next) => {
// ...
next()
})
/*后置全局守卫,跳转之后执行,参数to,from * to:进入的目标路由对象 * from:离开的路由对象 * */
router.afterEach((to,from)=>{
//...
})
在本例中
1、使用全局前置守卫beforeEach验证用户是否已经登录,如果没登录跳转到登录页(假设sessionStorage中字段login-Token有值就是登录)
2、使用全局后置守卫afterEach修改浏览器的标题栏
router.beforeEach((to,from,next)=>{
const token = sessionStorage.getItem('login-Token')
if(['/login','/404'].indexOf(to.path) !== -1){
next();
}else{
token ? next() : next('/login');
}
})
router.afterEach((to,from)=>{
window.document.title=to.meta.title
})
路由独享的守卫
单个路由有个钩子beforeEnter
以login所在的路由对象为例,修改路由配置,实现如果用户已经登录,跳转到首页
{
path: '/login',
component: Login,
beforeEnter :(to, from, next) => {
console.log('login路由独享守卫')
const token = sessionStorage.getItem('login-Token')
if(token){
next('/')
}else{
next()
}
}
组件内的守卫
可以在Vue组件内,利用钩子beforeRouteEnter,beforeRouteUpdate,beforeRouteLeave定义组件内的守卫
1、beforeRouteEnter(to,from,next)
组件内部先执行beforRouteEnter,再执行组件周期钩子函数beforeCreate,所以在执行beforRouteEnter钩子函数时,内部 this 是undefined
2、beforeRouteUpdate(to,from,next)
组件被复用且当前路由改变时,会触发路由钩子函数beforeRouteUpdate,内部可以访问组件实例 this
。
3、beforeRouteLeave(to,from,next)
导航离开该组件的对应路由时调用,内部可以访问组件实例 this
下面以login组件为例,下面利用beforeRouteEnter钩子实现login独享的守卫一样的功能
const Login = {
template: `<div><h1>登录</h1></div>`,
beforeRouteEnter(to, from, next){
const token = sessionStorage.getItem('login-Token');
if(token){
next('/')
}else{
next()
}
}
};
官方完整的导航解析流程
导航被触发。
在失活的组件里调用离开守卫。
调用全局的 beforeEach 守卫。
在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
在路由配置里调用 beforeEnter。
解析异步路由组件。
在被激活的组件里调用 beforeRouteEnter。
调用全局的 beforeResolve 守卫 (2.5+)。
导航被确认。
调用全局的 afterEach 钩子。
触发 DOM 更新。
用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。
与Vue 实例 生命周期(钩子函数)执行顺序比较
(离开组件的)beforeRouteLeave >>> beforeEach(全局路由) >>>(跳转到的路由组件内的) beforeRouteEnter >>> afterEach(全局路由) >>> vue实例的生命周期
还没有评论,来说两句吧...