vue --》动态路由的实现 (根据用户的权限来访问对应的模块)

  为了设置用户的访问权限,所以在一个vue工程中,往往需要前端和后端开发人员共同配合设置动态路由,

进而实现根据用户的权限来访问对应的模块

  1.首先在登录页面,前端跟据后端返回的路由信息进行配置,配置后存储到本地以便使用

login.vue页面
    在methods中:
  //配置路由的方法 getMenuList(){
       let menuList = '后端给你返回的数据'     let sysRouter
= []; let tempOne = {}; menuList.filter((menuOne, indexOne) => { tempOne = {}; tempOne.title = menuOne.name; //这几个属性均为路由的一些配置项以及所用到的一些信息,根据实际情况进行编写 tempOne.icon = menuOne.icon; tempOne.path = menuOne.perm; tempOne.redirect = menuOne.url; tempOne.children = []; tempOne.component = Main; //Main是个文件 每个页面都依赖于这个文件 let tempTwo = {}; if (menuOne.children.length > 0) { menuOne.children.filter((menuTwo, indexTwo) => {    tempTwo = {}; tempTwo.title = menuTwo.name; tempTwo.path = menuTwo.url; tempTwo.component = () => import(`@/pages${menuTwo.path}.vue`); tempOne.children.push(tempTwo); }); } sysRouter.push(tempOne); });
        sessionStorage.setItem("sysRouter", JSON.stringify(sysRouter));
    },
  //点击登录按钮的方法
  submitBtn(){
    
let parm = {
                username: this.key,
                password: this.pwd,
             
            };
    api.login(parm).then(res => {
       if(res){
         //首先将你的所需要的信息存储到本地,例如token,用户信息的等
         //调用配置路由信息的方法
         //然后跳转到首页
         //最后刷新一下页面,不然会白屏

sessionStorage.setItem("loginToken", res.data.data.token);

          this.getMenuList();
           this.$router.push({
                       path: "/home/home"
                  });
 
           setTimeout(()=>{
                       window.location.reload();
                  },50)

       }
    })

   }

接下来就是最关键的一步 配置 router里面的index.js文件

import Vue from 'vue';
import Router from 'vue-router';
import store from '../store';
import Main from '@/pages/Main.vue';

Vue.use(Router);


/*
 * 
 *  路由重复点击 警告问题解决
 *  
*/ 
const originalPush = Router.prototype.push
Router.prototype.push = function push(location) {
  return originalPush.call(this, location).catch(err => err)
}



/*
 *---- 登录前不运行,刷新时运行,用addRoutes加载路由 begin ----
 */
let systemRouter = [];
let localRouter = window.sessionStorage.getItem('sysRouter'); //用于刷新时加载导航 功能和addRoutes等同1
if (localRouter) {
  //因为未登录 localRouter不存在,故不运行;只有刷新时才运行
  let localJsonRouter = JSON.parse(localRouter);
  systemRouter = localJsonRouter;
  systemRouter.filter(item => {
    //需要重新绑定 component
    item.component = Main;
    if (item.children.length > 0) {
      item.children.filter(itemTwo => {
        itemTwo.component = () => import(`@/pages${itemTwo.path}.vue`);
      });
    }
  });
} else {
  systemRouter = [];
}
/*
 *---- 登录前不运行,刷新时运行,用addRoutes加载路由 end ----
 */

// 定义其他路由 这一般都为3级路由
let otherRouter = [
  {
    path: '/menu2_0_1',
    title: '设计数据管理',
    icon: 'el-icon-s-opportunity',
    redirect: '/designDataManage/clientRequireManage',
    component: Main,
    children: [
      {
        path: '/designDataManage/clientRequireManage/requireFileList',
        title: '客户需求管理',
        component: () =>
          import(
            '@/pages/designDataManage/requireFileList/requireFileList.vue'
          )
      },
      {
        path: '/designDataManage/designDataManageHome/designDataList',
        title: '设计数据管理',
        component: () =>
          import(
            '@/pages/designDataManage/designDataList/designDataList.vue'
          )
      },
      {
        path: '/designDataManage/designDataManageHome/FLDataList',
        title: '设计数据管理',
        component: () =>
          import('@/pages/designDataManage/FLfileList/FLfileList.vue')
      },
      {
        path:
          '/designDataManage/designDataManageHome/workAfterFileList',
        title: '设计数据管理',
        component: () =>
          import(
            '@/pages/designDataManage/workAfterFileList/workAfterFileList.vue'
          )
      },
      {
        path: '/designDataManage/designDataManageHome/numFileList',
        title: '设计数据管理',
        component: () =>
          import(
            '@/pages/designDataManage/numFileList/numFileList.vue'
          )
      },
      {
        path: '/designDataManage/printFileManage/printFileList',
        title: '制版文件管理',
        component: () =>
          import(
            '@/pages/designDataManage/printFileList/printFileList.vue'
          )
      }
    ]
  },
  {
    path: '/menu3_0_1',
    title: '工艺数据管理',
    icon: 'el-icon-s-open',
    redirect: '/workDataMange/workDataMangeRepair',
    component: Main,
    children: [
      {
        path: '/workDataMange/workDataMangeRepair/workDataMangeList',
        title: '客户需求管理',
        component: () =>
          import(
            '@/pages/workDataMange/workDataManageList/workDataManageList.vue'
          )
      }
    ]
  },
  {
    path: '/menu4_0_1',
    title: '打样任务管理',
    icon: 'el-icon-s-order',
    redirect: '/printTaskManage/printTaskManageHome',
    component: Main,
    children: [
      {
        path:
          '/printTaskManage/printTaskManageHome/printTaskManageList',
        title: '编辑打样任务',
        component: () =>
          import(
            '@/pages/printTaskManage/printTaskManageList/printTaskManageList.vue'
          )
      }
    ]
  },
  {
    path: '/menu4_0_2',
    title: '打样任务管理',
    icon: 'el-icon-s-order',
    redirect: '/printOAManage/printOAManageHome',
    component: Main,
    children: [
      {
        path: '/printOAManage/printOAManageHome/prinOAkManageList',
        title: '编辑打样任务',
        component: () =>
          import(
            '@/pages/printTaskManage/printOAmanageList/printOAmanageList.vue'
          )
      },
      {
        path:
          '/printOAManage/printOAManageHome/prinOAkManageStartWorkList',
        title: '开工',
        component: () =>
          import(
            '@/pages/printTaskManage/prinOAkManageStartWorkList/prinOAkManageStartWorkList.vue'
          )
      },
      {
        path: '/printOAManage/printOAManageHome/paraDetail',
        name: 'paramaDetail',
        title: '工艺参数详情',
        component: () =>
          import(
            '@/pages/printTaskManage/prinOAkManageStartWorkList/paramaDetail.vue'
          )
      }
    ]
  },
  {
    path: '/menu5_0_2',
    title: '打样基线管理',
    icon: 'el-icon-s-order',
    redirect: '/printBasicLineManage/importantColorData',
    component: Main,
    children: [
      {
        path:
          '/printBasicLineManage/importantColorData/importantColorDataList',
        title: '关键颜色详情',
        component: () =>
          import(
            '@/pages/printBasicLineManage/importantColorDataList/importantColorDataList.vue'
          )
      }
    ]
  }
];

//声明路由对象,实例化VueRouter
const router = new Router({
  routes: [
    //登录路由
    {
      path: '/',
      name: 'login',
      component: () => import('@/pages/login.vue')
    },
    {
      path: '/error',
      name: 'error',
      component: () => import('@/pages/error.vue')
    },
    {
      path: '/resetPassword',
      name: 'resetPassword',
      component: () => import('@/pages/checkPassword/resetPassword.vue')
    },
    {
      path: '/checkNameAndEmail',
      name: 'checkNameAndEmail',
      component: () => import('@/pages/checkPassword/checkNameAndEmail.vue')
    },
    ...systemRouter,
    ...otherRouter
  ]
});

/* * 加载页面之前 钩子函数
 
   * 使用场景:一般用在跳转前需要做校验的地方
   * to:Route即将要进入的目标 路由对象;
   * from:Route当前导航正要离开的路由;
   * next:Function一定要调用该方法来resolve这个钩子。执行效果依赖next方法的调用参数。
   * 
*/
router.beforeEach(function (to, from, next) {
  store.dispatch('updateActItem', to.path);

  /*--- 动态绑定路由格式 begin ---*/
  let systemRouter = [];
  let localRouter = window.sessionStorage.getItem('sysRouter'); //用于刷新时加载导航
  //beforeEach,一步小心就进入到了他的死循环,浏览器都会崩亏,需要在一开始就加判断,拿到路由了,就直接next(),
  if (localRouter) {
    let localJsonRouter = JSON.parse(localRouter);
    systemRouter = localJsonRouter;
    systemRouter.filter(item => {
      //需要重新绑定 component
      item.component = Main;
      if (item.children.length > 0) {
        item.children.filter(itemTwo => {
          itemTwo.component = () =>
            import(`@/pages${itemTwo.path}.vue`);
        });
      }
    });
  } else {
    systemRouter = [];
  }
  if (window.sessionStorage.getItem('sysRouter') == null) {
    //不加这个判断,路由会陷入死循环 !!!!
    router.addRoutes(systemRouter); //动态加载路由
  }



  store.dispatch('updateMenuList', systemRouter);
  next();
  /*--- 动态绑定路由格式 end ---*/
});
export default router;

 

  

posted @ 2019-11-13 18:36  我是一名好程序员  阅读(1215)  评论(0编辑  收藏  举报