当前位置: 首页 > news >正文

Vue3+Element+TS动态菜单+按钮权限控制实现探索

1.动态获取权限并根据获取权限转换成相对应的router

根据请求获取菜单数据,对菜单数据进行转换,分别进行下面几步:

/*** 组件地址前加斜杠处理*/
export function addSlashToRouteComponent(routeList: AppRouteRecordRaw[]) {routeList.forEach((route) => {const component = route.component as string;if (component) {const layoutFound = LayoutMap.get(component);if (!layoutFound) {route.component = component.startsWith("/") ? component : `/${component}`;}}route.children && addSlashToRouteComponent(route.children);});return routeList;
}

利用import函数+通配符,引入匹配的所有vue页面,如下:

const LayoutMap = new Map<string, () => Promise<typeof import("*.vue")>>();

以及const dynamicViewsModules = import.meta.glob("../../views/**/*.{vue,tsx}");

该map会生成一个以页面路径为key的,带有@import动态引入的方法为值的对象,这是可以通过处理key字符串,通过获取的菜单列表匹配对应的path,最终的component 就等于dynamicViewsModules[path]

function dynamicImport(dynamicViewsModules: Record<string, () => Promise<Recordable>>, component: string) {const keys = Object.keys(dynamicViewsModules);const matchKeys = keys.filter((key) => {const k = key.replace("../../views", "");const startFlag = component.startsWith("/");const endFlag = component.endsWith(".vue") || component.endsWith(".tsx");const startIndex = startFlag ? 0 : 1;const lastIndex = endFlag ? k.length : k.lastIndexOf(".");return k.substring(startIndex, lastIndex) === component;});if (matchKeys?.length === 1) {const matchKey = matchKeys[0];return dynamicViewsModules[matchKey];} else if (matchKeys?.length > 1) {console.log("Please do not create `.vue` and `.TSX` files with the same file name in the same hierarchical directory under the views folder. This will cause dynamic introduction failure");return;}
}

处理后最终返回的数据就是生成router树状结构 

2.动态添加路由addRoute

const menuRecordRoutes: RouteRecordRaw[] = Object.entries(menuRoutes).map(([, config]) => config).sort((a: any, b: any) => a.order - b.order) as RouteRecordRaw[];
menuRecordRoutes.forEach((route) => {router.addRoute(route);});

这里有个值得注意的地方如果是该菜单列表下有多个子菜单需要将子菜单也添加进去,如:

menuRecordRoutes.forEach((route) => {router.addRoute(route);if (route?.children?.length) {route.children.forEach((child) => {child.name = route.name?.toString() + "-" + child.name?.toString();if (route.name) {router.addRoute(route.name, child);}});}});

上图中后面一个router.addRoute是针对每个子菜单进行router添加,并且这里还有一个坑:

如果不同的菜单下的子菜单的name属性是一样的话 这里可能会把前面一个添加的子菜单给覆盖了,因为router中的name 属性是唯一的,所以这里对子菜单的name做了一个拼接:将父菜单名称和子菜单名称拼接到一起作为子菜单的新名称。另外这个name属性非常重要,如果name属性中含有特殊符号(如:name=detail@id),页面中如果使用了类似这样的页面跳转:router.push({ name: "detail", params: { id: row.id } }); 则会导致路由不匹配的问题

3.自定义指令控制按钮显隐 

//main.ts中引用
const app = createApp(App);
// 全局注册 自定义指令(directive)
setupDirective(app);
import type { App } from "vue";import { hasPerm } from "./permission";// 全局注册 directive
export function setupDirective(app: App<Element>) {// 使 v-hasPerm 在所有组件中都可用app.directive("hasPerm", hasPerm);
}
//自定义指令的自定义方法
export const hasPerm: Directive = {mounted(el: HTMLElement, binding: DirectiveBinding) {// 「超级管理员」拥有所有的按钮权限const { authList } = useUserStoreHook();const { value } = binding;let result = false;if (authList.length && value) {if (Array.isArray(value)) {result = value.every((ele) => authList.includes(ele));} else {result = authList.includes(value);}}if (!result) {el.parentNode && el.parentNode.removeChild(el);}return result;},
};

页面中使用

<el-button v-hasPerm="['xxx']" :icon="Delete" size="small" text type="primary">删 除</el-button>

至此,动态菜单和按钮权限功能完成 

相关文章:

Vue3+Element+TS动态菜单+按钮权限控制实现探索

1.动态获取权限并根据获取权限转换成相对应的router 根据请求获取菜单数据&#xff0c;对菜单数据进行转换&#xff0c;分别进行下面几步&#xff1a; /*** 组件地址前加斜杠处理*/ export function addSlashToRouteComponent(routeList: AppRouteRecordRaw[]) {routeList.fo…...

五款公司源代码加密软件推荐|代码防泄密解决方案

在当今数字化的世界中&#xff0c;源代码的泄露无疑是一场灾难。对于依赖加密软件保护关键信息的企业和个人来说&#xff0c;这种泄露不仅可能导致数据失窃&#xff0c;还可能损害企业的声誉和客户的信任。面对这种严峻的形势&#xff0c;我们迫切需要一种全面而有效的加密软件…...

【spring】Security 密码加密算法

Spring Security 提供了多种密码加密算法&#xff0c;用于在存储用户密码时进行加密&#xff0c;以增强安全性。 查看org.springframework.security.crypto.factory.PasswordEncoderFactories 以下是一些常用的密码加密算法&#xff1a; BCryptPasswordEncoder&#xff1a; 这…...

IO系列(一) -一文带你读懂 java 中的IO流!

一、摘要 说到 IO&#xff0c;相信大家都不陌生&#xff0c;英文全称&#xff1a;Input/Output&#xff0c;即输入/输出&#xff0c;通常指数据在内部存储器和外部存储器或其他周边设备之间的输入和输出。 比如我们常用的SD卡、U盘、移动硬盘等等存储文件的硬件设备&#xff…...

代码随想录算法训练营第六天| 242. 有效的字母异位词、349. 两个数组的交集、202. 快乐数、1. 两数之和

哈希表理论基础 [LeetCode] 242. 有效的字母异位词 [LeetCode] 242. 有效的字母异位词 文章解释 [LeetCode] 242. 有效的字母异位词 视频解释 题目: 给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字母异位词。 注意&#xff1a;若 s 和 t 中每个字符出…...

【python】中的可迭代对象、迭代器、生成器

结论 凡是实现了__iter__() 方法的类都称之为可迭代对象&#xff0c;但 __iter__() 方法的返回值只能是迭代器和生成器for 循环的本质是先调用 __iter__() 方法&#xff0c;然后不断调用返回值的 __next__() 方法&#xff0c;直至报出异常 StopIteration&#xff0c;可迭代对象…...

短视频矩阵系统源码/saas--总后台端、商户端、代理端、源头开发

短视频矩阵系统源码/saas--总后台端、商户端、代理端、源头开发 搭建短视频矩阵系统源码的交付步骤可以概括为以下几个关键环节&#xff1a; 1. **系统需求分析**&#xff1a;明确系统需要支持的功能&#xff0c;如短视频的上传、存储、播放、分享、评论、点赞等。 2. **技术选…...

K8s:二进制安装k8s(单台master)

目录 一、安装k8s 1、拓扑图 2、系统初始化配置 2.1关闭防火墙selinx以及swap 2.2设置主机名 2.3在每台主机中添加hosts&#xff0c;做映射 2.4调整内核参数&#xff0c;将桥接的ipv4流量传递到iptables&#xff0c;关闭ipv6 2.4时间同步 3、部署docker引擎&#xff0…...

C++类和对象下——实现日期类

前言 在学习了类和对象的六大成员函数后&#xff0c;为了巩固我们学习的知识可以手写一个日期类来帮助我们理解类和对象&#xff0c;加深对于其的了解。 默认函数 构造函数 既然是写类和对象&#xff0c;我们首先就要定义一个类&#xff0c;然后根据实际需要来加入类的数据与函…...

252 基于MATLAB的自适应差分阈值法检测心电信号的QRS波

基于MATLAB的自适应差分阈值法检测心电信号的QRS波&#xff0c;QRS波群反映左、右心室除极电位和时间的变化&#xff0c;第一个向下的波为Q波&#xff0c;向上的波为R波&#xff0c;接着向下的波是S波。通过GUI进行数据处理&#xff0c;展示心率和QRS。程序已调通&#xff0c;可…...

SSIM(Structural Similarity),结构相似性及MATLAB实现

参考文献 Wang, Zhou; Bovik, A.C.; Sheikh, H.R.; Simoncelli, E.P. (2004-04-01). “Image quality assessment: from error visibility to structural similarity”. IEEE Transactions on Image Processing. 13 (4): 600–612. Bibcode:2004ITIP…13…600W. CiteSeerX 10.…...

第十六章-消费者-PUSH方式(一)

16.1 准备阶段 先从一段官方示例代码开始 public class Consumer {public static void main(String[] args) throws InterruptedException, MQClientException {// 初始化consumer&#xff0c;并设置consumer group nameDefaultMQPushConsumer consumer new DefaultMQPushCo…...

【C++要哮着学】初识C++,什么是C++?什么是命名空间?什么又是缺省函数?

文章目录 前言1、C简介1.1、什么是C1.2、C起源1.3、C发展 2、C关键字&#xff08;C98&#xff09;3、命名空间3.1、命名空间的定义及使用3.2、命名空间的嵌套3.3、命名空间的三种使用方式3.3.1、加命名空间名称及作用域限定符3.3.2、使用using将命名空间中某个成员引入3.3.3、使…...

Lua 数字格式化

在编程中&#xff0c;对数字进行格式化是一项常见的任务&#xff0c;特别是当我们需要在用户界面中显示数据或生成报告时。在 Lua 中&#xff0c;我们可以使用一些简单而有效的函数来实现数字的格式化。在本文中&#xff0c;我们将介绍一个由几个函数组成的小型 Lua 库&#xf…...

Java入门基础学习笔记13——数据类型

数据类型的分类&#xff1a; 基本数据类型 引用数据类型 基本数据类型&#xff1a;4大类8种类型&#xff1a; 定义整形用int&#xff0c;再大的数用long。 package cn.ensource.variable;public class VariableDemo2 {public static void main(String[] args) {//目标&#x…...

使用Docker+Jar方式部署微服务工程(前后端分离)看着一篇就够了

本篇教程的使用到的技术有springboot、springcloud、Nacos、Docker、Nginx部署前后端分离访问的微服务。 部署一下Nacos 首先我们需要在服务器中&#xff08;或者本地部署启动一下Nacos&#xff09;&#xff0c;这里我采用服务器的方式进行部署&#xff0c;这里有一点不一样的…...

红外遥控和LCD1602

26.1.1 红外线简介 人的眼睛能看到的可见光按波长从长到短排列&#xff0c;依次为红、橙、黄、绿、青、蓝、紫。其中红光的波长范围为 0.62&#xff5e;0.76μm&#xff1b;紫光的波长范围为 0.38&#xff5e;0.46μm。比紫光波长还短的光叫紫外线&#xff0c;比红光波长还长的…...

房屋出租管理系统需求分析及功能介绍

房屋租赁管理系统适用于写字楼、办公楼、厂区、园区、商城、公寓等商办商业不动产的租赁管理及租赁营销&#xff1b;提供资产管理&#xff0c;合同管理&#xff0c;租赁管理&#xff0c; 物业管理&#xff0c;门禁管理等一体化的运营管理平台&#xff0c;提高项目方管理运营效率…...

高精度模拟算法

高精度模拟算法 高精度加法 extern string m,n; extern int a[MAX],b[MAX],ans[MAX]; void addition(){int _mmax(m.size(),n.size());reverse(m.begin(),m.end()),reverse(n.begin(),n.end());//转置原字符串for(int i0;i<m.size();i) a[i]m[i]-0;//字符型以ASCII码存储&…...

Ansible简介版

目录 架构 环境部署 一、Ansible安装部署 1.yum安装Ansible 2.修改主机清单文件 3.配置密钥对验证 4.ansible-doc 5.看被控主机 二、常用模块 1.Command模块 2.Shell模块 3.Cron模块 1.添加 2.删除 4.User模块 5.Group模块 1.创建组 ​编辑 ​编辑 ​编辑…...

OpenClaw技能系统深度指南:打造能干活、守规矩、够聪明的工具化 AI 助手

手把手教你一键部署OpenClaw&#xff0c;连接微信、QQ、飞书、钉钉等&#xff0c;1分钟全搞定&#xff01; AI 智能体想从只会动嘴皮子的“聊天机器人”变成真正能干活的“行动派”&#xff0c;能不能熟练使用工具就是一道分水岭。OpenClaw 的 Skills 系统&#xff0c;说白了就…...

手把手教你用GD32F30x的定时器搞定BLDC电机霍尔信号捕获(附完整代码)

手把手教你用GD32F30x的定时器实现BLDC电机霍尔信号精准捕获 当你的GD32F30x开发板已经连接好BLDC电机的霍尔传感器&#xff0c;却发现转速计算总是不准确时&#xff0c;问题往往出在定时器的配置细节上。本文将带你从寄存器层面拆解霍尔信号捕获的全流程&#xff0c;解决实际开…...

5个痛点解决:ComfyUI-KJNodes让工作流效率提升60%的实战指南

5个痛点解决&#xff1a;ComfyUI-KJNodes让工作流效率提升60%的实战指南 【免费下载链接】ComfyUI-KJNodes Various custom nodes for ComfyUI 项目地址: https://gitcode.com/gh_mirrors/co/ComfyUI-KJNodes ComfyUI-KJNodes是一套功能强大的ComfyUI自定义节点集合&…...

ChatGLM-6B真实反馈:用户对话满意度调查结果分享

ChatGLM-6B真实反馈&#xff1a;用户对话满意度调查结果分享 1. 引言&#xff1a;一次真实的对话体验调查 最近&#xff0c;我们围绕ChatGLM-6B智能对话服务进行了一次小范围的用户满意度调查。这不是一份冷冰冰的技术评测报告&#xff0c;而是一次真实的对话体验分享。我们邀…...

设计师福音:Z-Image-Turbo_UI界面实现草图到成品的快速转化

设计师福音&#xff1a;Z-Image-Turbo_UI界面实现草图到成品的快速转化 你是不是也遇到过这样的场景&#xff1f;脑子里有一个绝妙的创意&#xff0c;手绘了一张草图&#xff0c;但要把这个草图变成一张精美的成品图&#xff0c;却需要花费数小时甚至数天的时间&#xff0c;在…...

告别拼写红线:Vim-galore教你打造专属拼写检查系统

告别拼写红线&#xff1a;Vim-galore教你打造专属拼写检查系统 【免费下载链接】vim-galore :mortar_board: All things Vim! 项目地址: https://gitcode.com/gh_mirrors/vi/vim-galore 你是否厌倦了在Vim中写作时不断出现的拼写错误红线&#xff1f;想要一个强大而灵活…...

Jaspersoft Studio 动态字体颜色设置实战指南

1. 为什么需要动态字体颜色&#xff1f; 在报表开发中&#xff0c;数据可视化是提升信息传达效率的关键手段。想象一下&#xff0c;当你的老板查看月度销售报表时&#xff0c;如果所有数字都是千篇一律的黑色&#xff0c;他需要花费多少时间才能找到异常数据&#xff1f;而如果…...

极简音乐工具:重新定义纯粹听歌体验

极简音乐工具&#xff1a;重新定义纯粹听歌体验 【免费下载链接】tonzhon-music 铜钟 (Tonzhon.com): 免费听歌; 没有直播, 社交, 广告, 干扰; 简洁纯粹, 资源丰富, 体验独特&#xff01;(密码重置功能已回归) 项目地址: https://gitcode.com/GitHub_Trending/to/tonzhon-mus…...

避坑指南:MATLAB调用ROS2话题时,消息类型错误‘std_msgs/String’怎么办?

MATLAB与ROS2通信避坑指南&#xff1a;消息类型错误的深度解析与实战解决方案 当你在MATLAB中尝试与ROS2系统建立通信时&#xff0c;是否遇到过这样的报错&#xff1a;"Error using ros2subscriber. The message type std_msgs/String is invalid."&#xff1f;这看似…...

如何快速掌握PathOfBuilding:流放之路终极角色构建规划神器

如何快速掌握PathOfBuilding&#xff1a;流放之路终极角色构建规划神器 【免费下载链接】PathOfBuilding Offline build planner for Path of Exile. 项目地址: https://gitcode.com/GitHub_Trending/pa/PathOfBuilding 还在为《流放之路》复杂的天赋树和装备搭配而头疼…...