当前位置: 首页 > news >正文

vue+element后台管理系统,从后端获取路由表,并正常渲染

概述

    公司后台管理系统,需要从后端获取路由表,并正确渲染。结合看到的帖子 基于vue-router的动态权限实现方案,昨天将这个需求实现了。
    实现这个问题,有两个关键点。

  1. 登陆系统和刷新页面时,使用router.addRoutes添加需要补充的路由表
  2. router.beforeEach中,手动将路由表加到router.options.routes

    公司后台管理系统开发使用的模板是后台管理系统模板vue-admin-template。需要新增或改动的文件主要有4个:

  1. 在store/modules文件夹下新增的menu.js:处理并存储从后端获取的路由
  2. 修改router/index.js:只保留登陆页面的路由,其他和业务板块相关路由都删掉
  3. 修改permission.js:实现刷新页面时动态添加路由表,并手动给router.options.routes赋值
  4. 修改checkPwd.vue:登陆成功时,将后端获取的路由表存到localstorage

    下面结合代码做具体说明:


第一步

从后端获取的路由表,是不能直接通过router.addRoutes添加到路由表里,需要先修改component属性的值。我是统一在menu.js中修改。menu.js中有三大部分内容。 routerMap(component属性值和业务模块的映射),menu对象,generateRoutesFromMenu和transferChildren(处理路由表)

routerMap是这样的:

const routerMap = {
    'Layout':() => import('@/views/layout/Layout'),
    'reportProIntro': () => import('@/views/reportSystem/reportProIntro/index'),
    'reportProDetail': () => import('@/views/reportSystem/reportProDetail/index'),
    'collectionDaily': () => import('@/views/reportSystem/collectionDaily/index'),
    'performanceRanking': () => import('@/views/reportSystem/performanceRanking/index')
    }

menu对象是这样的:

const menu = {
    state:{
        items:[]
    },
    mutations:{
        ADD_MENU: (state,menuItems) => {
            if(menuItems.length == 0){
                state.items = [];
            }else{
                state.items = menuItems;
            }
        }        
    },
    actions:{
        addMenu:({commit},menuItems) => {
            let menu = generateRoutesFromMenu(menuItems)
            menu.push(asyncRouterMap[0]);
            commit('ADD_MENU',menu);            
        }
    }
}
export default menu

generateRoutesFromMenu和transferChildren是这样的:

function generateRoutesFromMenu(menu = []){    
    menu[0].component = routerMap.Layout;
    menu[0].redirect = 'reportProIntro';
    menu[0].name = 'Example';
    menu[0].meta = { title: '报表中心', icon: 'example' };
    menu[0].children = transferChildren(menu[0].children);      
    return menu
}

function transferChildren(childrenArr){    
    //格式化name,component,meta属性  
    console.log(childrenArr)  
    childrenArr.map((cur,index)=>{
        cur.name = cur.path;
        cur.component = routerMap[cur.path];
        cur.meta = {'title':cur.title}
        if(cur.children.length > 0){
            transferChildren(cur.children)
        }
    })
    return childrenArr
}

因为后台返回的路由表格式不一样,大家要根据实际情况进行改动,改成可用的路由表。

menu.js中把路由表的处理和存储都做好了。在需要存储路由表的地方,使用dispatch,调用addMenu方法即可。

第二步

写好了menu.js后,再来修改permission.js文件。permission.js有两处需要改。

  • 刷新页面时,如果localStorage中有permission(checkPwd登录成功时,获取的路由表),则将路由表存到到vuex中,再取出来,通过router.addRoutes挂载到路由上
let permission = JSON.parse(window.localStorage.getItem('permission'));
/* 刷新页面时候加载路由 */
if(permission){
    store.dispatch('addMenu',permission)
    router.addRoutes(store.getters.menuitems) 
}else{
    router.push({
        name: "checkPwd"
      })
}
  • router.beforeEach中,手动将可用路由表menuitems加到router.options.routes
store.getters.menuitems.forEach((item,index) => {
    router.options.routes[index+1] = item;
}) 

router.beforeEach中的这段代码,每次路由跳转时,都会调用。本项目中,路由表是通过router.options.routes渲染到菜单栏,而router.addRoutes并不会改变router.options.routes的值,所以,如果不手动加上,那么菜单将不能正常渲染出来。

第三步

改好了permission.js文件,再来修改checkPwd.vue。这是系统的登录页面,密码验证通过后,做三件事。

  1. 将后端返回的路由表,存到localStorage中,window.localStorage.setItem('permission', menu);//menu:string类型
  2. 将后端取到的路由表,存到vuex中,this.$store.dispatch('addMenu',menuArr);//menuArr:数组类型
  3. 第一次登陆时,将新增的路由通过addRoutes加到router中

    if(!this.hasPermission){
         this.$router.addRoutes(this.menuitems);      
    }

总结

menu.js中将拿到的路由表进行处理,转化为可以直接addRoutes的路由表
permission是处理刷新时,路由的挂载和router.options.routes的赋值
checkPwd存储拿到的路由表。

我在做的时候,踩过的坑有:

  1. 第一次登录时,不渲染。原因是第一次登陆时,permission为空,没有调用addRoutes,路由没挂载
  2. 菜单栏,相同路由有多个。原因是在给router.options.routes赋值时,采用了push方法。

以上就是我要分享的内容,不足的地方还请大家多多指正。

相关文章:

  • 以太坊分片:Overview and Finality
  • MySQL自定义函数递归查询父节点和子节点
  • “加息”道路越走越窄,小牛在线需主动自省求变
  • Cetos 7 防火墙设置
  • 阿里云 Caused by: redis.clients.jedis.exceptions.JedisDataException: ERR invalid password
  • 职场思想分享003 | 如何能让自己说话办事考虑的更周到?
  • Docker Enterprise 2.1 版本正式上线,全新特性先睹为快!
  • 【Zabbix】如何使用Zabbix进行IPMI监控?
  • Auto Encoder用于异常检测
  • 简单读!spring-mvc源码之url的暴露之路
  • DNS域名解析之搭建公司内部域--技术流ken
  • 认识CoreData - 初识CoreData
  • 对import的理解,python中的package和module概念
  • linux统配符
  • LeetCode刷题(Java)
  • python3.6+scrapy+mysql 爬虫实战
  • 分享的文章《人生如棋》
  • [译]Python中的类属性与实例属性的区别
  • 【前端学习】-粗谈选择器
  • E-HPC支持多队列管理和自动伸缩
  • Java深入 - 深入理解Java集合
  • Python学习笔记 字符串拼接
  • React+TypeScript入门
  • spring cloud gateway 源码解析(4)跨域问题处理
  • windows下mongoDB的环境配置
  • Xmanager 远程桌面 CentOS 7
  • zookeeper系列(七)实战分布式命名服务
  • 分享一份非常强势的Android面试题
  • 关于List、List?、ListObject的区别
  • 基于Javascript, Springboot的管理系统报表查询页面代码设计
  • 两列自适应布局方案整理
  • 区块链技术特点之去中心化特性
  • 设计模式 开闭原则
  • 一个普通的 5 年iOS开发者的自我总结,以及5年开发经历和感想!
  • scrapy中间件源码分析及常用中间件大全
  • ![CDATA[ ]] 是什么东东
  • # Maven错误Error executing Maven
  • $.each()与$(selector).each()
  • %check_box% in rails :coditions={:has_many , :through}
  • (待修改)PyG安装步骤
  • (附源码)springboot金融新闻信息服务系统 毕业设计651450
  • (规划)24届春招和25届暑假实习路线准备规划
  • (三)docker:Dockerfile构建容器运行jar包
  • (原创)Stanford Machine Learning (by Andrew NG) --- (week 9) Anomaly DetectionRecommender Systems...
  • (转)C#调用WebService 基础
  • (最全解法)输入一个整数,输出该数二进制表示中1的个数。
  • **Java有哪些悲观锁的实现_乐观锁、悲观锁、Redis分布式锁和Zookeeper分布式锁的实现以及流程原理...
  • .NET 表达式计算:Expression Evaluator
  • .Net调用Java编写的WebServices返回值为Null的解决方法(SoapUI工具测试有返回值)
  • /run/containerd/containerd.sock connect: connection refused
  • @AliasFor注解
  • [Android] Amazon 的 android 音视频开发文档
  • [C/C++]关于C++11中的std::move和std::forward
  • [C/C++]数据结构 深入挖掘环形链表问题
  • [C++ 从入门到精通] 12.重载运算符、赋值运算符重载、析构函数