Vue Router使用next函数死循环问题

3,890 阅读1分钟

需求背景

项目中使用账号验证码登录,访问页面时需要判断当前是否为登录态,后端接口是否登录都会返回200状态码,需要通过返回值来判断。大概思路为: 在导航的beforeEach函数中根据登录状态判断是否正常进入页面或进入登录页。

踩坑记录

// 	最初代码实现
router.beforeEach(async (to: Route, _: Route, next: any) => {
  NProgress.start()
  if (UserModule.isLogin) {
    if (to.path === '/login') {
      next({ path: '/', query: to.query })
    } else {
      next()
    }
  } else {
    // 未登录时跳转到登录页
    next('/login')
  }
})

在访问页面时回导致白屏,控制台报错如下,如果在这个函数里打印会发现router.beforeEach函数一直在执行

尝试多次后发现是next函数导致的死循环,我们看下官网是如何介绍next函数的: 可以看到next函数在有参和无参的时候是不一样的,当我们传参时,会中断当前导航然后进行一个新的导航,此时我们的beforeEach()函数会被再次调用,而next()不会重新触发beforeEach()函数。比如当想进入的是/home页,函数执行遇到 next('/login') 时,会重新触发beforeEach(),next('/login') 会接着被执行...如此产生死循环的问题。所以我们将代码略加修改如下:

router.beforeEach(async (to: Route, _: Route, next: any) => {
  NProgress.start()
  if (UserModule.isLogin) {
    if (to.path === '/login') {
      next({ path: '/', query: to.query })
    } else {
      next()
    }
  } else {
    // 不能直接到login页,会出现死循环
    if (to.path === '/login') {
      next()
    } else {
      next({
        path: '/login',
      })
    }
  }
})

完美解决(撒花)