动态路由初体验,存在不足,欢迎点评指正~

前言:在之前的项目中,菜单是动态获取的,而路由是写死的,配置路由的时候只要保证路由的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根据后端菜单数据生成动态路由相关推荐

  1. 七十三、Vue项目城市详细页的动态路由,Banner布局和公用图片画廊组件拆分

    2020/11/04. 周四.今天又是奋斗的一天. @Author:Runsen 写在前面:我是「Runsen」,热爱技术.热爱开源.热爱编程.技术是开源的.知识是共享的.大四弃算法转前端,需要每天的 ...

  2. Jasper Report 6.8 根据后台数据生成动态报表(JRXML文件实现)(三)JRXML文件生成过程(支持json,bean,map list数据源)

    1.生成头信息及页面 protected Element createPageXmlFileRoot( ) {DftRptMaster dftRptMaster = rptInfo.getDftRpt ...

  3. 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 ...

  4. vue根据权限生成动态路由、导航栏

    基本思路: 1,创建vueRouter,用公共路由实例化 2,创建需要根据权限筛选的路由对象(在路由对象,添加必要的权限判断字段) 3,登录完成,由后端配合返回当前用户的权限集合 4,筛选出有权限的路 ...

  5. Python之——生成动态路由轨迹图

    一.scapy简介与安装 scapy( http://www.secdev.org/projects/scapy/)是一个强大的交互式数据包处理程序,它能够对数据包进行伪造或解包,包括发送数据包.包嗅 ...

  6. VUE 路径拦截, 开放页面, 基于动态路由, 拦截器

    vue 动态路由参考 https://router.vuejs.org/zh/guide/essentials/dynamic-matching.html main.js 只会加载一次, 我们在mia ...

  7. django3,vue前后端分离数据请求

    下面使用vue2的写法,因为vue3也支持vue2的编写方法 运行django后端项目,端口需要设置为和前端项目不同 (luichun) [dalaojun@localhost dalaojun]$ ...

  8. 2022/9/5 嵌套路由(靠路由在vue里渲染套渲染),动态路由匹配以及开启propos配置动态路由

    嵌套路由 通过路由实现组件的嵌套展示 在about内嵌套路由 <template><div class="about-container"><h3&g ...

  9. vue 后台获取路由表,addRouters动态路由

    近日公司要求管理端动态管理路由,在登录时从后端获取路由配置动态生成路由 最大的bug出在,component属性运用import引入时,会找不到模块 无论使用import或者require,在引入一个 ...

最新文章

  1. php.exe php-cgi.exe php-win.exe的区别
  2. 人工智能应用,德国AI公司
  3. Docker 安装Centos,Tomcat,Jdk等相关的自定义(Dockerfile)镜像
  4. spring-chapter02-IoC Container
  5. 多线程java_由浅入深地介绍Java多线程,让你如何快速进入Java多线程的学习
  6. UTM 用户线程模型
  7. CSDN Blog推出专属的离线发布工具 - CSDN剪影
  8. python调用程序压缩文件_Python在后台自动解压各种压缩文件的实现方法
  9. linux 下拉式 终端,Gnome桌面的下拉式终端: Guake
  10. 阿里巴巴-码出高效+阿里巴巴Java开发手册(华山版)PDF下载
  11. 全球互联网进入后美国时代:在世界互联网大会上的演讲
  12. 小猫爪:PMSM之FOC控制01-Clark变换
  13. 数据结构——中国邮递员问题
  14. java 随机生成姓名_java生成随机姓氏中文人名
  15. mysql存储特殊表情符号_解决mysql存储特殊文字(表情符号)utf8mb4-阿里云开发者社区...
  16. day7_操作excel的三种方式
  17. 数字转换成英文 金额转成英文大写
  18. 腾讯让企业微信连接微信,这是针对钉钉的精准打击吗?
  19. fits文件读取代码
  20. java娘_如何调教Java娘来优化MC!

热门文章

  1. 基于稀疏网的PPP-RTK理论与应用-笔记
  2. 认识计算机操作系统ppt,使用操作系统,认识计算机.ppt
  3. #今日论文推荐# 多模态时序数据如何自监督?墨尔本理工等最新《自监督表示学习:多模态与时序数据》,全面阐述最新方法体系
  4. 〖产品思维训练白宝书 - 产品思维认知篇③〗- 产品思维 VS 技术思维
  5. 2.爬虫之xpath选择器selenium模块
  6. pandas读取webd的csv文件
  7. NB-IoT的低功耗特性原理解说
  8. 模糊控制——隶属函数
  9. cannot find symbol
  10. 正交,独立,相关及之间的关系