vue利用全局导航守卫做登陆后跳转到未登陆前指定页面

有这样一个场景:若是你在登陆以前输入了http://localhost:8080/oauth2-mgm-app/#/userManage,想进入userManage页面,可是因为没有登陆,系统是不会让你进入这个页面,以后会被定向到login页面。可是在登陆以后,认为你有这个权限了,就须要从新定向到userManage页面。大体流程图如图1所示:html

图1 登陆后跳转到未登陆前指定页面流程图vue

  在vue-route的官方文档里其实有给到过这个demo,官方文档连接在此:https://router.vuejs.org/zh/guide/advanced/meta.html。可是不是很符合咱们的需求,因而稍加改动,先上代码,搭配流程图可能更容易理解:后端

router.beforeEach((to, from, next) => {
  var asideMenuConfig = sessionStorage.getItem("asideMenuConfig");
  // 验证当前路由全部的匹配中是否须要有登陆验证的
  if (to.matched.some(record => record.meta.requiresAuth)) {
    // 这里能够将cookie里是否存有token做为验证是否登陆的条件
    // 请根据自身业务须要修改
    // 本段代码根据是否有权限菜单做为是否登陆依据
    if (asideMenuConfig) {
      //校验所跳路由是否在配置菜单中
      if (asideMenuConfig.indexOf(to.path) != -1 || to.path == "/index" || to.path == "/login") {
        if(sessionStorage.getItem('redirect')!=null){
          var redirect=sessionStorage.getItem('redirect');
          if(to.path == redirect){//解决next()无限循环
            next()
          }else{
            next({
              path: redirect
            });
          }
        }else{
          next();
        }
      } else {
        next({
          path: from.path
        })
      }
    } else {
      sessionStorage.setItem('redirect', to.fullPath);
      next({
        name: 'login'
      })
    }
  } else {
    next();
  }
})

  系统以是否有权限菜单做为是否登陆依据,此处的权限菜单(不一样人有不一样的权限,所显示的菜单也不同)由后端送出,处理成本身想要的树结构(例如样例代码中的asideMenuConfig,如图2所示)以后保存下来,此为前提。还有一种就是利用token验证做为登陆依据,根据本身的业务须要吧,此处不展开。数组

图2 asideMenuConfigcookie

  首先要在route.js定义路由(代码为节选):在路由元信息(meta字段)中添加一个对象,里面包含:requiresAuth(是否须要权限),title(子菜单名),parent(所属菜单名)session

{
     path: '/RoleManage',
     name: 'RoleManage',
     component: () => import("@/pages/UserManage/roleManage"),
     meta: {
          requiresAuth: true,
          title: '角色管理',
          parent:"用户管理"
     }
},

  而后咱们须要遍历$rout.matched来检查路由记录中的meta字段,这些在官方文档中已经写的很清楚了,这里就不细细张开了。这里重点看下some() 方法,some()测试数组中的某些元素是否经过了指定函数的测试。app

to.matched.some(record => record.meta.requiresAuth)表示的是只要有一个页面的meta里的requiresAuth为true,即须要权限,则to.matched.some()返回true。
  最后还有一处代码须要注意的是:

有人是否是就想了,获取了登录前保存的页面路径就能够直接跳转到目标页面了,即写成下列这种形式,可是此举会致使页面一直无限循环调用导航守卫。ide

if(sessionStorage.getItem('redirect')!=null){
    var redirect=sessionStorage.getItem('redirect');
    next({
        path: redirect
    });
}else{
    next();
}    

缘由是必定要调用next()来 resolve 这个导航守卫钩子,可是next()有参数和无参数是不同的,执行效果依赖next()的调用参数。函数

  next(): 进行管道中的下一个钩子。若是所有钩子执行完了,则导航的状态就是confirmed(确认的)。测试

  next()或者next({path:'/'})跳转到一个不一样的地址。当前的导航被中断,而后进行一个新的导航。你能够向next传递任意位置对象,且容许设置诸如repace:true、name:'home'之类的选项以及任何用在route-link的to prop或router.push中的选项。

注意:确保要调用next(),不然钩子就不会被 resolved。

相关文章
相关标签/搜索