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

embedded/2025/1/20 5:39:09/

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/embedded/155392.html

相关文章

AWS S3 跨账户访问 Cross Account Access

进入S3对应的存储桶&#xff0c;上面选项选权限&#xff0c;存储桶策略 -- 编辑&#xff0c;输入对应的policy。 完全控制&#xff0c;包含上传删除权限&#xff0c;policy如下&#xff1a; {"Version": "2012-10-17","Statement": [{"Si…

【记录52】el-table-column 添加fixed属性 滚动条无法滑动

问题&#xff1a; el-table-column 添加fixed属性 滚动条无法滑动 使用element UI组件&#xff0c;用到el-table的el-table-column的fixed属性时&#xff0c;当滚动条长度小于固定列时&#xff0c;滚动条无法通过鼠标去点击滑动操作 原因 fixed是用来固定列的属性&#xff0c;其…

nodejs后端ws与http结合共享一个服务器,前端websocket发送信息后端ws接收信息,使用Map定型数组设置ID

//服务端代码 const httprequire(node:http); const WebSocketrequire(ws);const serverhttp.createServer(); //创建websocket服务 const wssnew WebSocket.WebSocketServer({server}); //创建定型数组 const clientsnew Map();wss.on(connection,(ws)>{ //设置ws的IDclie…

微软SCCM:企业级系统管理的核心工具

目录 摘要 1. 引言 2. SCCM的基本概念 2.1 什么是SCCM? 2.2 SCCM的历史 3. SCCM的架构 3.1 中心服务器 3.2 数据库 3.3 管理点(Management Point) 3.4 分发点(Distribution Point) 3.5 客户端代理 3.6 报告服务 4. SCCM的核心功能 4.1 软件部署与管理 4.2 操…

无降智o1 pro——一次特别的ChatGPT专业模式探索

这段时间和朋友们交流 ChatGPT 的使用心得&#xff0c;大家都提到一个很“神秘”的服务&#xff1a;它基于 O1 Pro 模型&#xff0c;能够在对话里一直保持相对高水平的理解和回复&#xff0c;不会突然变得“降智”。同时&#xff0c;整体使用还做了免折腾的网络设置——简单一点…

速通Docker === 常用命令

目录 Docker命令 镜像操作 容器操作 基础操作 启动参数 容器内部操作 打包成指定文件 发布镜像 总结 镜像操作 容器操作 启动容器参数 容器内部操作 打包镜像 启动指定镜像的容器 发布镜像 Docker命令 启动一个nginx,并将它的首页改为自己的页面&#xff0c;发布…

数据可视化如何推动文旅行业的创新与发展

文旅行业作为25年国家重点政策照顾的行业&#xff0c;各家公司都在倾力打造相关的数字化产品。但是文旅行业相比较数据分析来说&#xff0c;目前困扰行业的难点在于面对海量数据信息如何将这些转化成有益信息是文旅行业面临的重要课题。因此&#xff0c;数据可视化逐渐收到了文…

在线图片压缩工具

在线图片压缩工具&#xff0c;无需登录&#xff0c;无需成本&#xff0c;用完就走。 包括中文和英文版本。 官网地址&#xff1a; https://compress.openai2025.com/ 效果&#xff1a;