vue addRoute 实现子账号权限管理

前言

系统在用了一段时间后,产品经理提出了新建子账号并可配置菜单权限的需求。配置子账号拥有部分菜单权限,并在子账号登录后,在地址栏直接输入本不属于该子账号的页面路由,要求重定向到404页面,即实现拦截。

开始

经过各种查阅资料,决定使用addRoute 动态添加路由。后台在登录后会返回账户菜单,是一个code的str合集,这个code对应每个菜单的code,是前后台约定好的。

步骤如下:
1、router/index.js:定义初始路由constantRoutes 和动态变化的路由DynamicRoutes ;
2、generateRoutes.js:(文件可以放在utils下,我放在了assets下)这个文件定义了generateRoutes方法,动态过滤路由,通过后台返回的code 合集,和DynamicRoutes 作比对,生成需动态添加的路由,然后用 router.addRoute()添加 ;
3、login.vue:在登录后,后台返回了该账户的code合集,调用generateRoutes 方法动态生成导航 ;
4、router/index.js:
① 路由守卫 ;
② router.onReady() 函数里写异步操作,用于已登录状态下刷新页面获取code合集并生成动态导航 ;

代码

router/index.js

//静态路由
const constantRoutes = [
    {
    
    {
    
    
      path: '/login',
      name: 'login',
      component: (resolve) => require(['../views/admin/login.vue'], resolve),
      meta:{
    
    title:'登录',needLogin:false,noLeft:true}
    }];
 //动态路由
 export const DynamicRoutes = [
  {
    
    // 首页
   path: '/index/',
   name: 'index',
   component:(resolve) => require(['../views/index.vue'], resolve),
   meta:{
    
    title:'首页',head:true,code:'v1'}
 },
 .
 .
 .
 ] ;
 const createRouter = () => new Router({
    
    
  mode: 'history',
  base: 'cs',
  routes: constantRoutes
 })
 const router = createRouter();
 // 路由守卫
 router.beforeEach((to, from, next)=>{
    
    
    if(to.matched.some(res=>('needLogin' in res.meta) && (res.meta.needLogin == false))){
    
    //不需要登录的页面
      if((to.path == '/login') && (window.sessionStorage['user_token'])){
    
    
      //登录页面 且 有token(说明登录过)
        next('/index');
      }else{
    
    
        next();
      }    
     }else{
    
    //需要登录
      if(window.sessionStorage['user_token']){
    
    //有token,登录状态下
          next() 
      }else{
    
    
        //无token,跳转回宣传首页
        next({
    
     path: '/login'});
      }
    }
 });
 //异步请求写在这里面
 router.onReady(() => {
    
    
   console.group('%c%s', 'color:red', `${
      
      new Date().getTime()}  路由完成初始导航----------`)
   console.log('添加前-所有活跃的路由记录列表', router.getRoutes())
  if(window.sessionStorage['user_token']){
    
    //已登录    
    userApi.getUserInfo().then(response => {
    
    
      if (response.code == 200) {
    
    
        let data = response.data;     
        let accountType =  data.accountType;//账户类型
        let authCodes =  data.authCodes;//code合集
        generateRoutes(accountType,authCodes);
        console.log('添加后-所有活跃的路由记录列表', router.getRoutes())
        console.groupEnd()
      }
    })  
  }
 });
 // 重置路由
 export function resetRouter () {
    
    
  const newRouter = createRouter()
  router.matcher = newRouter.matcher
 }
 export default router;

generateRoutes.js

import router,{
    
    DynamicRoutes} from '@/router/index'

//匹配动态生成导航
export function generateRoutes (accountType,authCodes) {
    
    
     //1.过滤需要的动态路由
     let realRoutes = [];
     if(accountType == 1){
    
    //主账号,有所有路由
       realRoutes = DynamicRoutes;
     }else{
    
    //子账号,根据authCodes过滤
       DynamicRoutes.forEach(item=>{
    
    
         if(!('children' in item)){
    
    
           if(authCodes.indexOf(item.meta.code) != '-1'){
    
    
             realRoutes.push(item);
           }
         }else{
    
    
           let arr = [];
           item.children.forEach(item1=>{
    
    
             if(authCodes.indexOf(item1.meta.code) != '-1'){
    
    
               arr.push(item1);
             }
           })
           if(arr.length > 0){
    
    
             let item2 = Object.assign({
    
    },item);
             item2.children = arr;
             realRoutes.push(item2);
           }
         }
       })
     }
     //2.添加路由
     realRoutes.forEach(route => {
    
    
        router.addRoute(route)
     })
     //3、添加输入其他路由时需要重定向的路由
     router.addRoute({
    
    
        path: '*',
        redirect: '/userCenter/myAccount'
     });

}

login.vue
登录成功后,调用生成导航的方法

import {
    
     generateRoutes } from '@/assets/js/func/generateRoutes.js'

export default {
    
    
  name: 'login',
  data(){
    
    
    login() {
    
    
      api.login(params).then(res=>{
    
    
			this.user=res.data;
	        let accountType =  this.user.accountType;
	        let authCodes =  this.user.authCodes;
	        //1.生成导航
	        generateRoutes(accountType,authCodes);
	        . 
	        .
	        .

	   })
   }
 }   

结束

在此记录问题,如有需要修改的地方,还请不吝赐教。文章借鉴:vue-router的addRoute方法实现权限控制

猜你喜欢

转载自blog.csdn.net/qq_39352780/article/details/122555875