doubleyong
管理员
管理员
  • 最后登录2020-10-29
  • 发帖数914
  • 最爱沙发
  • 喜欢达人
  • 原创写手
  • 社区居民
  • 忠实会员
阅读:295回复:0

[vue]Vue踩坑记 — beforeEach 中 next 方法

楼主#
更多 发布于:2020-08-23 15:28



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的时候可以让链接在跳转的时候不会留下历史记录。
知识需要管理,知识需要分享
游客


返回顶部

公众号

公众号