​ 在使用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函数
next:function(to,from,_next){
	if(to===undefined){
     //TODO
     
		//相当于beforeEach里面调用next(),也就是放行,return回去,继续执行beforeEach后面的语句
		return;
	}else if(typeof to=='string'){
     //TODO
     
		//相当于beforeEach里面调用next('/string'),此时当前要前往的path被改变了,所以继续调用一层router.beforeEach。对新的path调用路由守卫进行校验,这种情况最容易出现死循环(死递归)
		router.to=to;
		router.beforeEach(router.to,rourer.from,next);
   		//回到上一层beforeEach,继续执行后面的代码
		return;
	}
}

router.beforeEach((to,from,next)=>{
	//程序员TODO
})

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’)方法
/loginnext(‘/login’)执行期间,当前要前往的url已经变成了/login,所以再一次调用beforeEach方法,方法第一行console.log(to.path);打印了当前要前往的url是/login
1beforeEach方法中第二行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);打印
1if(to.path===‘/login’)成立,打印console.log(1)
4继续执行next()方法,未携带参数,next方法return回到beforeEach,跳过else语句,执行console.log(4)

综上,尽量别在beforeEach函数内前面调用带参数的next()函数,但也不能一个next()方法都不写.

Logo

前往低代码交流专区

更多推荐