vue3+vue-router+vite 实现动态路由

文章中出现的代码是演示版本,仅供参考,实际的业务需求会更加复杂

什么是动态路由

在这里插入图片描述

什么场景会用到动态路由

举一个最常见的例子,比如说我们要开发一个后台管理系统,一般来说后台管理系统都会分角色登录,这个时候也就涉及到了权限,比如说这个后台管理系统现在有超级管理员,管理员,运维,财务等这几个角色,每个角色登录系统之后都会有不同的权限,超级管理员需要所有的权限,财务可能只需要财务相关的模块(菜单)以及按钮等,通常实现这种需求会有以下常见方案

路由表由前端去维护

也就是说我们已知这几个角色分别对应哪些权限,前端写好路由配置表,,后端只需要告诉你当前登录人是属于哪个角色,前端根据角色类型去写一个过滤函数,获取该角色所拥有的菜单以及按钮,然后动态的去添加路由,这样做有一个缺点就是,如果又增加了一个新的角色怎么办?某个角色想增加一些权限怎么办?这个时候前端就需要去新增或者修改代码,一点也不友好

路由表的数据由后端返回

这种也是常用的一种方式,可能我们的系统里面需要开发一些功能,如菜单管理,角色管理,用户管理等,也就是常说的权限中心,前端开发完的页面所对应的路由信息有后端去维护,这个时候我们在开发的时候需要约束某一种规则,比如所有页面都放到/src/views目标下面,然后通过菜单管理去维护数据,维护完的数据可以到角色管理里面去配置角色菜单,配置完角色,可以到用户管理里面给某个用户配置角色等一些列流程,这样的话即使新增一个角色,或者修改一个角色的角色菜单,前端都不需要去修改代码,只要在菜单管理里面维护好了数据,想怎么改怎么改,后端返回的数据格式可能如下:

[{path: "/application",name: "application",component: "Layout",title: "应用管理",show: true,icon: "",children: [{path: "",name: "application-index",component: "/application/index.vue",},],},{path: "/permission",name: "permission",component: "Layout",title: "权限管理",show: true,icon: "",children: [{path: "menu",name: "permission-menu",component: "/permission/menu/index.vue",title: "菜单管理",show: true,icon: "",},{path: "user",name: "permission-user",component: "/permission/user/index.vue",title: "用户管理",show: true,icon: "",},{path: "role",name: "permission-role",component: "/permission/role/index.vue",title: "角色管理",show: true,icon: "",},],},
]

其实仔细观察这个数据结构,是不是有点熟悉,path,name,component,children,我们好像手动维护路由表的时候也会用到这些属性

如何实现动态路由

实现动态路由其实就要用到vue-router提供的一个方法,叫addRoute在之前版本的时候是addRoutes,现在非版本的vue-router给废除了
addRoute()如何使用呢?可以看一下官方文档

当我们添加一个主路由的时候

router.addRoute({ path: '/permission', name: 'permission', component: () => import('xxxxx')})

添加子路由也就是嵌套路由

router.addRoute('主路由的name', { path: 'settings', component: AdminSettings })

在这里插入图片描述
既然我们已经知道了addRoute()方法如何使用,下面我们就可以去实现这部分逻辑
我们看一下官方文档的导航守卫里面的内容
在这里插入图片描述
在这里插入图片描述
在之前我们使用导航守卫的时候需要一个参数next()去控制是否放行以及去哪个页面,但是在新版本的vue-router里面可以不是用next(),当然你是用也行~

我们可以新建一个permission.ts文件

import router from "./index";
import { useSessionStorage } from "@vueuse/core";
import { StorageEnum } from "@/enum";
import { useUserStore } from "@/store";const whiteList = ["/login", "/404"];router.beforeEach(async (to) => {const token = useSessionStorage(StorageEnum.TOKEN, "").value;// 如果在白名单里面 并且 token 不存在if (whiteList.includes(to.path) && !token) {return true;} else {const { menuList, getMenuList } = useUserStore();// 如果为空数组,name就请求接口重新获取后端维护的路由数据if (!menuList.length) {await getMenuList();console.log("获取全部路由 =>", router.getRoutes());// 触发重定向 不这样写会导致刷新找不到路由 两种写法都行// return { path: to.fullPath };return to.fullPath;}}
});

这里我们可以看到一会return true一会return to.fullpath是为什么,通过官方导航守卫里面的介绍,我们可以知道的是
在这里插入图片描述
通过官方文档动态路由,我们可以直到
在这里插入图片描述
所以说return to.fullpath是官方告诉我们要这么使用,也是为了解决动态路由页面刷新的时候会出现页面空白或者404的问题
出现404的话比如说你在路由表中维护了下面路由映射

{path: "/:pathMatch(.*)",name: "page404",component: () => import("@/views/system/404.vue"),
}

上面说的主要是在全局导航守卫里面的一些使用及注意事项,我们可以看到并没有用到addRoute()这个方法,也没有出现拿到后端数据前端转换成路由表的相关代码,但是我们可以看到有一个getMenuList()函数,我们在开发的时候,肯定是要考虑到复用以及复杂逻辑抽取的问题,一个动态路由的实现会牵扯到很多知识点接口请求,vuex或者pinia状态维护,vue-router,vite里面怎么获取文件等
下面看一下如何获取到接口给的数据,转换成vue-router能够识别的数据
首先我们要看一个vite官方给提供的功能,我们拿到后端给的文件路径如上面代码出现的component字段,如/application/index.vue,这个文件可能在我们本地项目中的src/views/application/index.vue这个路径下
在这里插入图片描述
我们需要把它转换成一个下面的格式() => import('xxxx'),我们需要动态的去拼接获取文件,该怎么实现呢?
vite官方文档中有说明
在这里插入图片描述
需要使用import.meta.glob,这个时候我们可以打印一下import.meta.glob("../views/**"),看一下返回的到底是什么
在这里插入图片描述
返回的是一个对象,而对象的key我们可以拼接获取到,而value正是我们想要的动态获取的文件路径
以下代码仅供参考,有很多需要完善的地方,只为演示使用

import type { RouterType } from "@/router/type";
import router from "@/router";
import type { RouteRecordRaw } from "vue-router";export const useRouterConfig = () => {// 获取views目录下的所有的文件 不要使用@别名 const modules = import.meta.glob("../views/**");const asyncRoutes = ref<RouterType[]>([]);const addRoutes = (menus: RouterType[]) => {asyncRoutes.value = menus;filterAsyncRouter();// 动态添加 / 路由router.addRoute({path: "/",redirect: asyncRoutes.value[0].path,});};const filterAsyncRouter = () => {const routerLoop = (routes: RouterType[], ParentName?: string) => {routes.forEach((item) => {if (item.component === "Layout") {item.component = () => import("@/layout/index.vue");} else {item.component = resolveComponent(item.component);}const { title, show, icon, name, path, component, children } = item;const route: RouteRecordRaw = {component,path,name,meta: {title,show,icon,},children: children as any,};// 动态添加路由if (ParentName) {router.addRoute(ParentName, route);} else {router.addRoute(route);}if (item.children && item.children.length > 0) {routerLoop(item.children, item.name);}});};routerLoop(asyncRoutes.value);};const resolveComponent = (path: string) => {console.log(modules);// 拿到views下面的所有文件之后,动态拼接`key`去获取valueconst importPage = modules[`../views${path}`];if (!importPage) {throw new Error(`Unknown page ${path}. Is it located under Pages with a .vue extension?`);}return importPage;};return { addRoutes };
};

综上所述:

要想实现vite+vue-router实现动态路由我们需要用到

  • addRoute()
  • import.meta.glob()
  • 获取后端tree数据,递归循环,可能业务会有type类型,比如分为模块,菜单,页面,按钮等,到时候结合业务去实现逻辑
  • 导航守卫使用时的注意事项,否则会出现刷新白屏,或者路由访问死循环等

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/42209.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第4章 课程发布:模块需求分析,课程预览(模板引擎 静态页面),课程审核,课程发布(分布式事务,页面静态化:熔断降级),课程搜索(es索引)

1 模块需求分析 1.1 模块介绍 课程信息编辑完毕即可发布课程&#xff0c;发布课程相当于一个确认操作&#xff0c;课程发布后学习者在网站可以搜索到课程&#xff0c;然后查看课程的详细信息&#xff0c;进一步选课、支付、在线学习。 下边是课程编辑与发布的整体流程&#…

一.2.(1)双极型晶体三极管的结构、工作原理、特性曲线及主要参数

1.双极型晶体三极管的结构 学会区分P管和N管&#xff0c;会绘制符号 2.工作原理 无论是PNP 还是NPN&#xff0c;本质上放大时&#xff0c;都是发射结正偏&#xff0c;集电极反偏。&#xff08;可以简单理解为pn为二极管&#xff0c;每个三极管都有两个二极管&#xff09; 其中电…

前端面试题22(js中sort常见的用法)

JavaScript 的 sort() 方法是数组的一个非常强大的功能&#xff0c;用于对数组的元素进行排序。这个方法直接修改原数组&#xff0c;并返回排序后的数组。sort() 的默认行为是将数组元素转换为字符串&#xff0c;然后按照字符串的 Unicode 字典顺序进行排序。这意味着如果你试图…

Linux内存管理--系列文章柒——硬件架构

一、引子 之前文章讲解的是系统的虚拟内存&#xff0c;本章讲述这些硬件的架构和系统怎样统一管理这些硬件的。 二、物理内存模型 物理内存模型描述了计算机系统中的物理内存如何由操作系统组织和管理。它定义了物理内存如何划分为单元&#xff0c;如何寻址这些单元以及如何…

powershell美化工具Oh My Posh安装教程

1. 安装Oh My Posh 进入Oh My Posh官网&#xff0c;可根据不同平台进行下载 windows下可以直接在微软商店下载 2. 安装Nerd Fonts字体 进入Nerd Fonts官网&#xff0c;选择自己喜欢的字体下载解压后&#xff0c;全选所有文件&#xff0c;右键选择安装即可&#xff08;忽略LICEN…

ARM_Linux驱动开发——字符设备驱动开发(上)

目录 一、Linux驱动开发思维 二、Linux驱动开发分类 三、“ ARM_Linux驱动开发——字符设备驱动开发 ” 字符设备驱动简介 前言 在分享Linux驱动开发之前&#xff0c;我想带大家首先回顾一下裸机驱动开发和Linux驱动开发的区别。 1、运行环境和操作系统&#xff1a; 裸机驱…

Apache Seata 高可用部署实践

本文来自 Apache Seata官方文档&#xff0c;欢迎访问官网&#xff0c;查看更多深度文章。 本文来自 Apache Seata官方文档&#xff0c;欢迎访问官网&#xff0c;查看更多深度文章。 Apache Seata 高可用部署实践 Seata 高可用部署实践 使用配置中心和数据库来实现 Seata 的高…

使用Spring Boot和自定义缓存注解优化应用性能

在现代应用开发中&#xff0c;缓存是提高系统性能和响应速度的关键技术之一。Spring Boot提供了强大的缓存支持&#xff0c;但有时我们需要更灵活的缓存控制。本文将介绍如何使用Spring Boot和自定义缓存注解来优化应用性能。 1. 为什么需要自定义缓存注解&#xff1f; Sprin…

AI算力革命:GPU租赁与算力市场的未来趋势

在数字化和智能化的时代背景下&#xff0c;人工智能&#xff08;AI&#xff09;的快速发展已成为全球科技领域的焦点。AI算力作为支撑其发展的关键因素&#xff0c;正以前所未有的速度改变着我们的生活和工作方式。其中&#xff0c;GPU租赁模式的兴起&#xff0c;不仅解决了AI算…

ASP.NET Web应用中的 Razor Pages/MVC/Web API/Blazor

如果希望使用ASP.NET Core创建新的 Web 应用程序&#xff0c;应该选择哪种方法&#xff1f;Razor Pages还是 MVC&#xff08;模型-视图-控制器&#xff09;&#xff0c;又或者使用Web API Vue/React/......。 每种方法都有各自的优点和缺点。 什么是 MVC&#xff1f; 大多数服…

轻松设置:服务器域名配置全攻略

目录 前置条件 在阅读本篇内容之前&#xff0c;请先确保以下物料已准备好&#xff1a; 一台公网服务器&#xff0c;服务正常运行申请完成的域名&#xff0c;在对应域名服务商后台正常DNS解析域名备案完成可选条件&#xff1a;有https访问请求时&#xff0c;需要申请SSL证书 …

微信小程序的“小鱼在乎”日程计划系统-计算机毕业设计源码51307

摘要 本文介绍了一种基于微信小程序和Spring Boot后端服务的“小鱼在乎”日程计划系统。该系统结合了前端微信小程序的便捷交互与后端Spring Boot框架的稳健性能&#xff0c;为用户提供了一款功能全面、体验出色的日程管理工具。 “小鱼在乎”日程计划系统涵盖了多种功能&#…

DNS正向解析与反向解析实验

正向解析 安装bind软件 [rootlocalhost ~]# dnf install bind bind-utils -y修改主配置文件/etc/named.conf [rootlocalhost ~]# vim /etc/named.conf重启DNS服务&#xff08;named&#xff09; [rootlocalhost ~]# systemctl restart named编辑数据配置文件。在/var/named…

Opencv的基本操作(一)图像的读取显示存储及几何图形的绘制

文件的读取、显示、存取 cv2.imread(imagepath,IMREAD.xxx) 读取图像cv2.imshow(窗口名称,mat图片) 显示图像cv2.imwrite(保存的位置,img) 保存图像 # 1. 读取图像 原始图片路径&#xff0c;图片读取模式 cv2.imread(imagepath,IMREAD.xxx)cv2.IMREAD_COLOR 彩色模式读取 cv2…

Gemini for China 大更新,现已上架 Android APP!

官网&#xff1a;https://gemini.fostmar.online/ Android APP&#xff1a;https://gemini.fostmar.online/gemini_1.0.apk 一、Android APP 如果是 Android 设备&#xff0c;则会直接识别到并给下载链接。PC 直接对话即可。 二、聊天记录 现在 Gemini for China&#xff…

【论文笔记】UniST:通用预训练城市时空预测模型

目录 写在前面1. 通用时空模型的挑战与能力特性2. 构建通用时空模型UniST2.1 大规模时空预训练2.2 时空知识规则引导提示学习 3. UniST的实验与分析3.1 模型预测效果3.2其他实验分析 写在前面 文章标题&#xff1a;UniST: A Prompt-Empowered Universal Model for Urban Spati…

每日一题~ leetcode 402 (贪心+单调栈)

click me! 这个贪心的推导在leetcode上已经很明确了。 click me! 删除k个数&#xff0c;可以先考虑删除一个数。这也是一种常见的思路。&#xff08;如果进行同样的操作多次&#xff0c;可以先只 考虑一次操作如何实现&#xff0c;或者他的影响。完成这一次操作后&#xff0c;…

Rabnud博士加入了一个社交圈。起初他有5个朋友。他注意到他的朋友数量以下面的方式增长。第1周少了1个朋友......

Rabnud博士加入了一个社交圈。起初他有5个朋友。他注意到他的朋友数量以下面的 方式增长。第1周少了1个朋友&#xff0c;剩下的朋友数量翻倍&#xff1b;第2周少了2个朋友&#xff0c;剩下的朋友数量 翻倍。一般而言&#xff0c;第N周少了N个朋友&#xff0c;剩下的朋友数量翻倍…

程序员下班为什么不关电脑?难道在偷偷加班?!

不管是周围的程序员朋友还是网上的很多程序员朋友&#xff0c;在下班后都是习惯不关电脑的&#xff0c;关上显示器&#xff0c;拿上手机&#xff0c;快乐下班&#xff01; 那么&#xff0c;为什么程序员下班都不关电脑&#xff1f;难道他们在偷偷加班&#xff1f; 其实&#x…

锂电池寿命预测 | Matlab基于改进的遗传算法优化BP神经网络的锂离子电池健康状态SOH估计

目录 预测效果基本介绍程序设计参考资料 预测效果 基本介绍 主要流程如下: 1、首先提取“放电截止电压时间”作为锂电池间接健康因子&#xff1b; 2、然后引入改进的遗传算法对BP神经网络的模型参数进行优化。 3、最后 NASA 卓越预测中心的锂电池数据集 B0005、B0006、B0007对…