使用vue-next-admin框架后台修改动态路由

devtools/2025/1/22 23:18:11/

vue-next-admin框架是一个基于 Vue 3 和 Vite 构建的后台管理系统框架。它采用了最新的前端技术栈,旨在提供一个高效、灵活、现代化的管理后台解决方案。该框架主要用于构建功能丰富且易于定制的管理后台应用,适合各种中大型项目。
 

其主要特点包括:

  1. Vue 3 和 Composition API:使用 Vue 3 的新特性,如 Composition API,提高了代码的可读性和可维护性。
  2. Vite 构建工具:使用 Vite 作为构建工具,提供更快的热重载速度和更优化的构建性能。
  3. 现代化的前端技术栈:包括 Vue Router、Vuex(或 Pinia)、Element Plus(或其他 UI 组件库),以及 TypeScript 支持。
  4. 高度可定制的界面和功能:支持多种主题切换、权限管理、动态路由、国际化等功能,方便开发人员根据需求进行二次开发和定制。
  5. 响应式设计:适应不同屏幕尺寸和设备,提升用户体验。

总的来说,Vue Next Admin 是一个功能强大、灵活、易于扩展的后台管理框架,适合用来开发现代化的后台管理系统。


Vue 动态路由的实现思路主要依赖于 Vue Router,动态路由允许根据用户的权限、角色、页面状态或其他因素动态地生成或改变路由配置。

今天我们要使用vue-next-admin框架通过后端动态的修改路由。


步骤如下:


1.首先,路由在src/router文件夹中。在router文件夹中有四个文件

backEnd.ts是后台控制路由的文件,我们需要使用后台控制时,需要修改里面的内容。
frontEnd.ts 是前端控制路由的文件。
index.ts 文件中,告诉我们需要后端控制路由时:isRequestRoutes 为 true
而修改isRequestRoutes的文件在src/stores/themeConfig

而修改isRequestRoutes的文件在src/stores/themeConfig文件夹中。
需要找到isRequestRoutes改为true。


route.ts 这个是路由文件,不管是后端还是前端控制,只要是需要出现的页面,都需要在这个页面进行注册。
现在我们就可以后端的控制路由。


2. 现在需要修改backEnd.ts文件中的内容。
 
获取路由菜单。


1.需要先给前端的数据关了,然后自己添加
 
2.我们需要转换数据格式,将一维数据转换为多维数据。
 3.数据转换完成后,需要对比路由

 backEnd.ts页面代码如下:

javascript">import { RouteRecordRaw } from 'vue-router';
import { storeToRefs } from 'pinia';
import pinia from '/@/stores/index';
import { useUserInfo } from '/@/stores/userInfo';
import { useRequestOldRoutes } from '/@/stores/requestOldRoutes';
import { Session } from '/@/utils/storage';
import { NextLoading } from '/@/utils/loading';
import { dynamicRoutes, notFoundAndNoPower } from '/@/router/route';
import { formatTwoStageRoutes, formatFlatteningRoutes, router } from '/@/router/index';
import { useRoutesList } from '/@/stores/routesList';
import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
import { useMenuApi } from '/@/api/menu/index';
// import { console } from 'node:inspector';// 后端控制路由// 引入 api 请求接口
const menuApi = useMenuApi();/*** 获取目录下的 .vue、.tsx 全部文件* @method import.meta.glob* @link 参考:https://cn.vitejs.dev/guide/features.html#json*/
const layouModules: any = import.meta.glob('../layout/routerView/*.{vue,tsx}');
const viewsModules: any = import.meta.glob('../views/**/*.{vue,tsx}');
const dynamicViewsModules: Record<string, Function> = Object.assign({}, { ...layouModules }, { ...viewsModules });/*** 后端控制路由:初始化方法,防止刷新时路由丢失* @method NextLoading 界面 loading 动画开始执行* @method useUserInfo().setUserInfos() 触发初始化用户信息 pinia* @method useRequestOldRoutes().setRequestOldRoutes() 存储接口原始路由(未处理component),根据需求选择使用* @method setAddRoute 添加动态路由* @method setFilterMenuAndCacheTagsViewRoutes 设置路由到 pinia routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组*/
export async function initBackEndControlRoutes() {// 界面 loading 动画开始执行if (window.nextLoading === undefined) NextLoading.start();// 无 token 停止执行下一步if (!Session.get('token')) return false;// 触发初始化用户信息 pinia// https://gitee.com/lyt-top/vue-next-admin/issues/I5F1HPawait useUserInfo().setUserInfos();// 获取路由菜单数据const res = await getBackEndControlRoutes();console.log(backendRoutes(arrayToTree(res.data), dynamicRoutes[0].children));// return;if (res.code === 0) {// 存储接口原始路由(未处理component),根据需求选择使用useRequestOldRoutes().setRequestOldRoutes(JSON.parse(JSON.stringify(res.data)));// 处理路由(component),替换 dynamicRoutes(/@/router/route)第一个顶级 children 的路由dynamicRoutes[0].children = backendRoutes(arrayToTree(res.data), dynamicRoutes[0].children);// 添加动态路由await setAddRoute();}// 无登录权限时,添加判断// https://gitee.com/lyt-top/vue-next-admin/issues/I64HVOif (res.data.length <= 0) return Promise.resolve(true);await setFilterMenuAndCacheTagsViewRoutes();NextLoading.done();
}// 对比路由
// routes 后端返回
//  dynamic 前端路由
function backendRoutes(routes, dynamic) {// 将dynamic转换为Map 以提高查找的效率const dynamicMap = new Map(dynamic.map((v) => [v.path, v]));const filteredRoutes = [];routes.forEach((item) => {const route = dynamicMap.get(item.path);if (route) {route.meta.title = item.title;route.meta.icon = item.icon;if (item.children && item.children.length > 0) {route.children = backendRoutes(item.children, route.children);}filteredRoutes.push(route);} else {console.warn('路由未定义:' + item.path);}});return filteredRoutes;
}
// 一维转树形
function arrayToTree(items) {// 存储最终的树形结构const result = [];// 用于快速查找节点const map = [];// 首先将所有节点放在map中,以id为键,值为节点items.forEach((item) => {map[item.id] = { ...item, children: [] };});// 然后遍历map,将子节点放在对应的父节点的children数组中items.forEach((item) => {if (item.pid === null || item.pid === 0 || item.pid === undefined) {// 如果父节点为0,则将当前节点放在result中result.push(map[item.id]);} else {// 否则,找到父节点并添加到当前节点的children数组中if (map[item.pid]) {map[item.pid].children.push(map[item.id]);}}});return result;
}
/*** 设置路由到 pinia routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组* @description 用于左侧菜单、横向菜单的显示* @description 用于 tagsView、菜单搜索中:未过滤隐藏的(isHide)*/
export async function setFilterMenuAndCacheTagsViewRoutes() {const storesRoutesList = useRoutesList(pinia);storesRoutesList.setRoutesList(dynamicRoutes[0].children as any);setCacheTagsViewRoutes();
}/*** 缓存多级嵌套数组处理后的一维数组* @description 用于 tagsView、菜单搜索中:未过滤隐藏的(isHide)*/
export function setCacheTagsViewRoutes() {const storesTagsView = useTagsViewRoutes(pinia);storesTagsView.setTagsViewRoutes(formatTwoStageRoutes(formatFlatteningRoutes(dynamicRoutes))[0].children);
}/*** 处理路由格式及添加捕获所有路由或 404 Not found 路由* @description 替换 dynamicRoutes(/@/router/route)第一个顶级 children 的路由* @returns 返回替换后的路由数组*/
export function setFilterRouteEnd() {let filterRouteEnd: any = formatTwoStageRoutes(formatFlatteningRoutes(dynamicRoutes));// notFoundAndNoPower 防止 404、401 不在 layout 布局中,不设置的话,404、401 界面将全屏显示// 关联问题 No match found for location with path 'xxx'filterRouteEnd[0].children = [...filterRouteEnd[0].children, ...notFoundAndNoPower];return filterRouteEnd;
}/*** 添加动态路由* @method router.addRoute* @description 此处循环为 dynamicRoutes(/@/router/route)第一个顶级 children 的路由一维数组,非多级嵌套* @link 参考:https://next.router.vuejs.org/zh/api/#addroute*/
export async function setAddRoute() {await setFilterRouteEnd().forEach((route: RouteRecordRaw) => {router.addRoute(route);});
}/*** 请求后端路由菜单接口* @description isRequestRoutes 为 true,则开启后端控制路由* @returns 返回后端路由菜单数据*/
export function getBackEndControlRoutes() {let list = JSON.parse(localStorage.getItem('menus') || '[]');return {code: 0,type: 'adminMenu',data: list,};
}/*** 重新请求后端路由菜单接口* @description 用于菜单管理界面刷新菜单(未进行测试)* @description 路径:/src/views/system/menu/component/addMenu.vue*/
export async function setBackEndControlRefreshRoutes() {await getBackEndControlRoutes();
}/*** 后端路由 component 转换* @param routes 后端返回的路由表数组* @returns 返回处理成函数后的 component*/
export function backEndComponent(routes: any) {if (!routes) return;return routes.map((item: any) => {if (item.component) item.component = dynamicImport(dynamicViewsModules, item.component as string);item.children && backEndComponent(item.children);return item;});
}/*** 后端路由 component 转换函数* @param dynamicViewsModules 获取目录下的 .vue、.tsx 全部文件* @param component 当前要处理项 component* @returns 返回处理成函数后的 component*/
export function dynamicImport(dynamicViewsModules: Record<string, Function>, component: string) {const keys = Object.keys(dynamicViewsModules);const matchKeys = keys.filter((key) => {const k = key.replace(/..\/views|../, '');return k.startsWith(`${component}`) || k.startsWith(`/${component}`);});if (matchKeys?.length === 1) {const matchKey = matchKeys[0];return dynamicViewsModules[matchKey];}if (matchKeys?.length > 1) {return false;}
}

现在,后端动态路由修改完成。大家可以自己手动尝试一次。


http://www.ppmy.cn/devtools/152717.html

相关文章

前端入门(html)

目录 一、HTML简介 1、网站 2、网页 3、网页的构成 4、什么是HTML 二、常用浏览器及其内核 1、浏览器 三、web标准 1、为什么需要web标准 2、web标准的构成 一、HTML简介 1、网站 网站是指在因特网上根据一定的规则&#xff0c;使用 HTML 等制作的用于展示特定内容相…

【Elasticsearch入门到落地】6、索引库的操作

接上篇《5、安装IK分词器》 上一篇我们进行了IK分词器的安装与测试&#xff0c;本篇我们来学习ElasticSearch的索引库的操作&#xff0c;学习mapping映射属性以及CRUD操作。 一、前情回顾 我们在前几篇学习了ElasticSearch的基本概念&#xff0c;并动手搭建了ElasticSearch环…

将 AzureBlob 的日志通过 Azure Event Hubs 发给 Elasticsearch(3.纯python的实惠版)

前情&#xff1a; 将 AzureBlob 的日志通过 Azure Event Hubs 发给 Elasticsearch&#xff08;1.标准版&#xff09;-CSDN博客 将 AzureBlob 的日志通过 Azure Event Hubs 发给 Elasticsearch&#xff08;2.换掉付费的Event Hubs&#xff09;-CSDN博客 python脚本实现 厉害的…

数学基础 --线性代数之理解矩阵乘法

理解矩阵乘法的解析 矩阵乘法&#xff08;Matrix Multiplication&#xff09;是线性代数中的核心操作之一。在数学、几何和工程实际中&#xff0c;它不仅是一种代数运算规则&#xff0c;还承载着丰富的几何和映射意义。本文将从多个角度深入解析矩阵乘法&#xff0c;帮助读者理…

你还在用idea吗

从VIM、Emacs&#xff0c;到eclipse、Jetbrains, 再到VSCode&#xff0c;过去的三十年时间&#xff0c;出现了这三代IDE产品。现在属于AI的时代来了&#xff0c;最新一代的产品像Cursor、Windsurf&#xff0c;就在昨天&#xff0c;字节跳动发布了最新的IDE&#xff0c;就叫Trae…

Three.js实战项目01:vue3+three.js实现圣诞动画贺卡项目

文章目录 创建项目加载模型设置天空与水设置天空设置水纹添加点光源相机位置和文字切屏添加星星完整代码下载创建项目 创建vue3项目【christmas-app】: npm init vite@latest安装两个库: npm install three@0.153npm install gasp加载模型 // 导入three库 import *

【数学建模美赛速成系列】O奖论文绘图复现代码

文章目录 引言折线图 带误差棒得折线图单个带误差棒得折线图立体饼图完整复现代码 引言 美赛的绘图是非常重要得&#xff0c;这篇文章给大家分享我自己复现2024年美赛O奖优秀论文得代码&#xff0c;基于Matalab来实现&#xff0c;可以直接运行出图。 折线图 % MATLAB 官方整理…

【数据结构篇】顺序表 超详细

目录 一.顺序表的定义 1.顺序表的概念及结构 1.1线性表 2.顺序表的分类 2.1静态顺序表 2.2动态顺序表 二.动态顺序表的实现 1.准备工作和注意事项 2.顺序表的基本接口&#xff1a; 2.0 创建一个顺序表 2.1 顺序表的初始化 2.2 顺序表的销毁 2.3 顺序表的打印 3.顺序…