? 在使用vue路由守卫的beforeEach 方法时可能会出现无限递归,也就是死循环的问题,根本原因在于next()方法在不合适的地方错误调用所致,先来看一下官方对next()方法的解释:
beforeEach 方法体:
router.beforeEach((to, from, next) => {
})
经过我的测试了一些数据,大概猜测出next()方法的底层实现逻辑(别问为什么不看源码,不会ts,我搞后端的)
经过我的测试,实际上,next()方法的调用是个递归的过程
以下用粗略的js代码来还原next()过程可能发生了什么,有问题请指出:
let router={}
let router.to='xxx'
let router.from='xxx'
next:function(to,from,_next){
if(to===undefined){
return;
}else if(typeof to=='string'){
router.to=to;
router.beforeEach(router.to,rourer.from,next);
return;
}
}
router.beforeEach((to,from,next)=>{
})
router.beforeEach(router.to,rourer.from,next);
beforeEach和next是个轮流相互调用的过程,容易造成死循环
这里给出一种无死循环的样例:
router.beforeEach((to,from,next)=>{
console.log(to.path);
if(to.path==='/login'){
console.log(1)
next();
}else{
let user=localStorage.getItem('userInfo')?JSON.parse(localStorage.getItem('userInfo')):null;
if(user){
console.log(2)
next();
}else {
console.log(3)
next('/login');
}
}
console.log(4)
})
以下是一些测试样例:
当我未登录,前往'/content' 页面时,控制台打印情况:
/content
3
/login
1
4
4
打印内容 | 解释 |
---|
/content | 前往/content页面,console.log(to.path)执行 | 3 | 不是/login页面,又未在localStorage中获取到user相关信息,执行console.log(3),调用next(‘/login’)方法 | /login | next(‘/login’)执行期间,当前要前往的url已经变成了/login,所以再一次调用beforeEach方法,方法第一行console.log(to.path);打印了当前要前往的url是/login | 1 | beforeEach方法中第二行if(to.path===‘/login’)成立,console.log(1)打印1,执行next()方法 | 4 | 因为next方法中没携带参数,又return回来了,跳过else语句,执行beforeEach方法中的console.log(4) | 4 | 回到最外层的beforeEach方法,跳过else语句,再跳出到else语句外层,执行console.log(4) |
当我未登录,前往'/login' 页面时,控制台打印情况:
/login
1
4
打印内容 | 解释 |
---|
/login | 当前要前往的是/login页面,beforeEach第一行console.log(to.path);打印 | 1 | if(to.path===‘/login’)成立,打印console.log(1) | 4 | 继续执行next()方法,未携带参数,next方法return回到beforeEach,跳过else语句,执行console.log(4) |
综上,尽量别在beforeEach函数内前面调用带参数的next()函数,但也不能一个next()方法都不写.
|