Vue踩坑记 — beforeEach 中 next 方法

13,633 阅读2分钟

01 全局前置守卫介绍

使用 router.beforeEach 注册一个全局前置守卫:

const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
  // ...
})

当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于 等待中。 每个守卫方法接收三个参数:

to: Route: 即将要进入的目标 路由对象

**from: **Route: 当前导航正要离开的路由

**next: **Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数

02 next方法解析

next(): 不会触发 beforeEach

next('/xxx') 或者 next({ path: '/xxx' }) 跳到不同的地址都会再次执行 router.beforeEach 钩子函数。

03 next引发的错误

一、vue 全局前置守卫引起死循环
router.beforeEach((to,from,next) =>{
  if (sessionStorage.getItem("token")) {
     if(to.path === "/login"){
       next({path:"/dashboard"})
     }
     else{
       alert("1")
       next()
     }     
  }else{
    next({path: "/login"})   // 会再次执行前置导航守卫,因为路径变化
  }
})

解决方案:

router.beforeEach((to, from, next) => {
  let token = window.sessionStorage.getItem('token');
  if (to.path != '/login' && !token) {
    next({
      path: '/login'
    })
  } else {
    if (to.path == '/login' && token) {
      next('/dashboard')
    } else {     
      next()
    }
  }
})
二、vue-router 动态加载路由,可以实现,但是刷新页面就不显示了
if (to.name === 'Login') {
    next();
  } else {
    if (to.meta.requireAuth) { // 验证用户是否登录
      if (sessionStorage.getItem('isLogin')) {
        if(store.getters.getIsLogin && store.getters.getRefresh){
          // 如果用户登录了,页面refresh值为true,则重新添加路由
          store.dispatch('setNoRefresh'); //重新刷新设置为false
          DynamicAddRouter();//添加动态路由的方法
          next()
        }else{
          next();
        }
      } else {
        next({
          path: '/login'
        })
      }
    } else {
      if(store.getters.getRefresh){
        console.log("加载动态路由")
        // 如果用户登录了,页面refresh值为true,则重新添加路由
        store.dispatch('setNoRefresh'); //重新刷新设置为false
        DynamicAddRouter();//添加动态路由的方法
        next()
      }else{
        next();
      }
    }

解决方案:

动态加载路由后,将next()方法,改为next({ ...to, replace: true })

**注:**只将动态路由加载后的next方法,进行改变,如果全部改变,将进入到死循环

if (to.name === 'Login') {
  next();
} else {
  if (to.meta.requireAuth) { // 验证用户是否登录
    if (sessionStorage.getItem('isLogin')) {
      if(store.getters.getIsLogin && store.getters.getRefresh){
        // 如果用户登录了,页面refresh值为true,则重新添加路由
        store.dispatch('setNoRefresh'); //重新刷新设置为false
        DynamicAddRouter();//添加动态路由的方法
        next({ ...to, replace: true })
      }else{
        next();
      }
    } else {
      console.log(sessionStorage.getItem('isLogin'))
      next({
        path: '/login'
      })
    }
  } else {
    if(store.getters.getRefresh){
      console.log("加载动态路由")
      // 如果用户登录了,页面refresh值为true,则重新添加路由
      store.dispatch('setNoRefresh'); //重新刷新设置为false
      DynamicAddRouter();//添加动态路由的方法
      next({ ...to, replace: true })
    }else{
      next();
    }
  }

**解析:**replace属性为true的时候可以让链接在跳转的时候不会留下历史记录。

喜欢这篇文章,可以支持一下哟,分享、点赞、在看走一个,哈哈@_@

更多文章,请关注公众号

bug收集