vue根据后端菜单数据生成动态路由
动态路由初体验,存在不足,欢迎点评指正~
前言:在之前的项目中,菜单是动态获取的,而路由是写死的,配置路由的时候只要保证路由的path与菜单的index(elementUI的el-menu组件)相同就可以实现路由跳转,只是菜单改了的话,路由也得相应修改,否则就会找不到页面。当时之所以没有研究动态路由是觉得跳转的页面是路由指定的,如果路由变成动态获取的话,前端的页面文件命名和目录结构都得根据后端的数据调整,也不是很灵活,但是…最近后端调整了数据,发现好多路由没有匹配到,都跳转到了一个重定向/redirect页面,所以最终还是决定动手研究动态路由!
1.将router/index.js写死的路由注释掉(或者删除)
2. 新建asyncRouter.js用来根据菜单提取路由表,菜单结构如图:
name -> componentName
path -> url
component -> 由上级菜单的componentName加上本级菜单的componentName组成文件路径
meta的title -> menuName
具体代码:
/** @Author: Wushiqi* @Descripttion: 获取路由:遍历传入的菜单列表,拿取拼接路由所需的数据(path、name、title、component)* @Date: 2020-08-19 10:44:15* @LastEditor: Wushiqi* @LastEditTime: 2020-08-25 16:07:33*/
// Layout组件是项目中的主页面,切换路由时,仅切换Layout中的组件
import Layout from '@/layout'
export function getAsyncRoutes(routes) {const res = []routes.forEach(route => { // 所有菜单都是二级结构,一级没有页面功能,所以只要添加二级菜单的路由if (route.childMenuInfoTreeSet.length !== 0) {const children = []route.childMenuInfoTreeSet.forEach(menu => { // 二级菜单需匹配页面children.push({path: menu.url,name: menu.componentName.split('/')[1],// 此处使用require,由于import会有奇怪的错误component: (resolve) => require([`@/views${route.componentName + menu.componentName}`], resolve),meta: { title: menu.menuName }})})res.push({path: route.url,component: Layout,children: children})}})return res
}
3.在获取菜单的时候同时生成路由表:
逻辑:首次登录时获取菜单,同时执行getAsyncRoutes方法获取路由表,将得到的路由数据使用addRoutes添加到路由表,并且将每一项路由push到路由的options。注意一个坑:f5刷新页面时,会执行路由的跳转的操作,而再次获取菜单和路由这个操作是在路由跳转之后的,所以在刷新的时候就找不到起始的路由(除了写死的路由之外),解决办法是让再次获取菜单和路由的操作在路由跳转之前,我这边的思路是在第一次获取菜单时,将菜单存到sessionStorage,之后刷新的时候不再访问接口重新获取。
这是写死的路由(未添加动态数据):
这是添加了动态数据之后的路由:
获取菜单部分代码:
async created() {if (!sessionStorage.menu) { // 首次登陆获取菜单列表const response = await publicAPI.userMenuAPI() // 从后台获取菜单列表const data = response.data.data.menuListif (data.length > 0) {this.menuList = dataconst router = getAsyncRoutes(data) // 根据菜单提取路由this.$router.addRoutes(router)router.forEach(val => { // 将菜单提取出来的路由加到路由表this.$router.options.routes.push(val)})console.log(this.$router);sessionStorage.setItem('menu', JSON.stringify(data)) // 将菜单列表存到sessionStorage}} else { // 已有菜单不再重新获取this.menuList = JSON.parse(sessionStorage.menu)// 要重新将路由挂上去,否则点击菜单不会跳转页面const router = getAsyncRoutes(this.menuList)this.$router.addRoutes(router)router.forEach(val => { // 将菜单提取出来的路由加到路由表this.$router.options.routes.push(val)})}}
4.修改目录和文件名
根据下面拼接的结果调整目录
比如用户管理拼接完成是@/views/baseData/user,则目录是这个样子的
5.重定向
我的默认路由有一项是重定向,所有匹配不到的路由都会跳转到重定向页面。
改为动态路由之后发现,刷新的时候路由会跳转到重定向页面,所以要在重定向页面让路由跳转回原来的页面。
{path: '*',redirect: '/redirect/:path*'},{path: '/redirect',name: 'redirect',component: Layout,hidden: true,children: [{path: '/redirect/:path*',component: () => import('@/views/redirect/redirect')}]},
重定向页面代码:
<script>
export default {created() { // 重定向页面const { params } = this.$routeconst { path } = paramsif (path) {this.$router.push({ path: `/${path}` })} else {this.$router.push({ path: `${sessionStorage.toPath}` })}},render: function(h) {return h() // avoid warning message}
}
</script>
重定向页面的sessionStorage.toPage存的是刷新前访问的页面,相关代码添加在router.beforeEach里面
if (!to.redirectedFrom && to.path !== '/redirect') { // 如果不是重定向操作,就存下当前访问的路由地址sessionStorage.setItem('toPath', to.path)}
这样就完成动态路由啦~ 只是这样以后,刷新页面会先跳转至redirect页面,然后再跳转回原先的页面,刷新的速度变慢了,视觉上也会看见一闪的白屏,寻求更好的方法~
vue根据后端菜单数据生成动态路由相关推荐
- 七十三、Vue项目城市详细页的动态路由,Banner布局和公用图片画廊组件拆分
2020/11/04. 周四.今天又是奋斗的一天. @Author:Runsen 写在前面:我是「Runsen」,热爱技术.热爱开源.热爱编程.技术是开源的.知识是共享的.大四弃算法转前端,需要每天的 ...
- Jasper Report 6.8 根据后台数据生成动态报表(JRXML文件实现)(三)JRXML文件生成过程(支持json,bean,map list数据源)
1.生成头信息及页面 protected Element createPageXmlFileRoot( ) {DftRptMaster dftRptMaster = rptInfo.getDftRpt ...
- Vue iView Admin 动态路由菜单加载 前后端分离(springboot 2.x iview admin vue 前后端分离 模型设计器 动态数据权限...
宣传官网 xb.exrick.cn 在线Demo xboot.exrick.cn 开源版Github地址 github.com/Exrick/x-bo- 开发文档 www.kancloud.cn/ex ...
- vue根据权限生成动态路由、导航栏
基本思路: 1,创建vueRouter,用公共路由实例化 2,创建需要根据权限筛选的路由对象(在路由对象,添加必要的权限判断字段) 3,登录完成,由后端配合返回当前用户的权限集合 4,筛选出有权限的路 ...
- Python之——生成动态路由轨迹图
一.scapy简介与安装 scapy( http://www.secdev.org/projects/scapy/)是一个强大的交互式数据包处理程序,它能够对数据包进行伪造或解包,包括发送数据包.包嗅 ...
- VUE 路径拦截, 开放页面, 基于动态路由, 拦截器
vue 动态路由参考 https://router.vuejs.org/zh/guide/essentials/dynamic-matching.html main.js 只会加载一次, 我们在mia ...
- django3,vue前后端分离数据请求
下面使用vue2的写法,因为vue3也支持vue2的编写方法 运行django后端项目,端口需要设置为和前端项目不同 (luichun) [dalaojun@localhost dalaojun]$ ...
- 2022/9/5 嵌套路由(靠路由在vue里渲染套渲染),动态路由匹配以及开启propos配置动态路由
嵌套路由 通过路由实现组件的嵌套展示 在about内嵌套路由 <template><div class="about-container"><h3&g ...
- vue 后台获取路由表,addRouters动态路由
近日公司要求管理端动态管理路由,在登录时从后端获取路由配置动态生成路由 最大的bug出在,component属性运用import引入时,会找不到模块 无论使用import或者require,在引入一个 ...
最新文章
- php.exe php-cgi.exe php-win.exe的区别
- 人工智能应用,德国AI公司
- Docker 安装Centos,Tomcat,Jdk等相关的自定义(Dockerfile)镜像
- spring-chapter02-IoC Container
- 多线程java_由浅入深地介绍Java多线程,让你如何快速进入Java多线程的学习
- UTM 用户线程模型
- CSDN Blog推出专属的离线发布工具 - CSDN剪影
- python调用程序压缩文件_Python在后台自动解压各种压缩文件的实现方法
- linux 下拉式 终端,Gnome桌面的下拉式终端: Guake
- 阿里巴巴-码出高效+阿里巴巴Java开发手册(华山版)PDF下载
- 全球互联网进入后美国时代:在世界互联网大会上的演讲
- 小猫爪:PMSM之FOC控制01-Clark变换
- 数据结构——中国邮递员问题
- java 随机生成姓名_java生成随机姓氏中文人名
- mysql存储特殊表情符号_解决mysql存储特殊文字(表情符号)utf8mb4-阿里云开发者社区...
- day7_操作excel的三种方式
- 数字转换成英文 金额转成英文大写
- 腾讯让企业微信连接微信,这是针对钉钉的精准打击吗?
- fits文件读取代码
- java娘_如何调教Java娘来优化MC!