Vue3自定义指令实现按钮权限

一、需求前提

登录成功后,后端直接返回了用户的所有权限(路由权限+按钮权限),在已经实现菜单权限的基础上,实现每个页面的按钮权限,树形数据结构如下:

{
    "roles": ["admin"],
    "token": "12345678901234567890",
    "userInfo": {
                   "id": "1",
                   "username": "system",
                   "nickName": "system",
                   "email": null,
                   "phoneNumber": "13131234567",
                   "sex": "1",
                   "avatar": null,
                   "userType": "1"
                },
    "menus": [
        {
            "id": "1",
            "pid": "0",
            "menuName": "home",
            "type": 1,
            "path": "/home",
            "perms": "home",
            "icon": "iconfont icon-shouye",
            "sortNo": 0,
            "selected": null,
            "status": "0",
            "title": "首页",
            "redirect": "",
            "visible": "0",
            "remark": "首页",
            "name": "home",
            "meta": {
                "title": "首页",
                "isHide": false,
                "roles": [
                    "home"
                ],
                "icon": "iconfont icon-shouye",
                "tagsViewName": "首页"
            },
            "children": [],
        },
        {
            "id": "2",
            "pid": "0",
            "menuName": "screen",
            "type": 1,
            "path": "/screen",
            "perms": "screen",
            "icon": "iconfont icon-shuju",
            "sortNo": 3,
            "selected": null,
            "status": "0",
            "title": "信息大屏",
            "redirect": null,
            "visible": "0",
            "remark": "信息大屏",
            "name": "screen",
            "meta": {
                "title": "信息大屏",
                "isHide": false,
                "roles": [
                    "screen"
                ],
                "icon": "iconfont icon-shuju"
            },
            "children": [
              {
                  "id": "21",
                  "pid": "2",
                  "menuName": "firstScreen",
                  "type": 1,
                  "path": "/firstScreen",
                  "perms": "firstScreen",
                  "icon": "ele-FirstAidKit",
                  "sortNo": 0,
                  "selected": null,
                  "status": "0",
                  "title": "大屏1",
                  "redirect": null,
                  "visible": "0",
                  "remark": "大屏1",
                  "name": "firstScreen",
                  "meta": {
                      "title": "大屏1",
                      "isHide": false,
                      "roles": [
                          "firstScreen"
                      ],
                      "icon": "ele-FirstAidKit"
                  },
                  "children": [
                    {
                        "id": "211",
                        "pid": "21",
                        "menuName": "loadingData",
                        "type": 2,
                        "path": "loadingData",
                        "component": "",
                        "perms": "screen:firstScreen:loadingData",
                        "icon": "",
                        "sortNo": 0,
                        "selected": null,
                        "status": "0",
                        "title": "同步数据",
                        "redirect": null,
                        "visible": "0",
                        "remark": "同步数据",
                        "name": "loadingData",
                        "meta": {
                          "title": "同步数据",
                          "isHide": false,
                          "roles": [
                            "screen:firstScreen:loadingData"
                          ],
                          "icon": ""
                        },
                        "children": [],
                    },
                  ],
              },
            ],
        },
    ],             
}

 

二、实现思路

获取当前路由页面的权限,筛选出当前路由页面拥有的所有按钮权限,判断某个按钮是否拥有权限,没有权限就通过css设置为display:none

三、具体实现步骤(vue3+ts)

1.在src文件下新建directive文件,在directive文件中新建btnPermission.ts文件

具体目录结构如下:

2.在btnPermission.ts中

import type { App } from 'vue';
import { useUserInfo } from '/@/stores/userInfo';/*** 按钮权限指令-无按钮权限不显示* @directive 单个按钮权限验证(v-btnPermission="xxx")*/export function btnPermission(app: App) {app.directive('btnPermission', {mounted(el, binding) {// 1.从用户信息pinia中拿到用户信息(用户权限)const stores = useUserInfo();// 2.找到当前路由页面拥有的所有权限const btnArr = filterPath(stores.userInfos.menus, window.location.hash.slice(1))// 3.判断是否有当前按钮的权限,没有直接不显示if (!btnArr.find((item: any) => item.name == binding.value)) {el.style.display = 'none'}},});
}//递归工具函数---判断当前节点是否匹配目标路由
function filterPath(tree: any, path: string) {for (let i = 0; i < tree.length; i++) {const node = tree[i];if (node.path == path) {return node.children;} else {if (node.children && node.children.length > 0) {const result: any = filterPath(node.children, path);if (result) {return result;}}}}
}

 3.在directive文件下的index.ts中,注册自定义指令

import type { App } from 'vue';
import { btnPermission } from '/@/directive/btnPermission';/*** 导出指令方法:v-xxx* @methods btnPermission 按钮权限指令,用法:v-btnPermission*/export function directive(app: App) {// 按钮权限指令btnPermission(app)
}

 4.在目标页面中使用

  // v-btnPermission="'按钮权限的name值'",真实项目中的字段取用自行与后端协商<el-button size="default" v-btnPermission="'loadingData'" type="primary"@click="handleSubmit">同步数据</el-button>

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

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

相关文章

Multiple HTTP implementations were found on the classpath错误的解决方法

当我们的项目中集成了多个AWS相关Jar包时,有可能就会遇到这个错误: 错误信息: There is an issue with the connector Code: InvalidInput.InvalidConnectorConfiguration Message: The connector configuration is invalid. Message: Multiple HTTP implementations were f…

新手小白学JAVA_IDEA修改主题 设置背景图片

很多小白在刚刚使用IDEA的时候还不是很熟练 本文主要给大家提供一些使用的小技巧&#xff0c;希望能帮助到你 1.修改IDEA默认主题 IDEA的默认主题是黑色的&#xff0c;其实也可以选择其他的主题 我们一起来试一试吧~ 2.修改IDEA背景图片 IDEA的背景图片也是可以自定义的 我们…

蓝桥杯专题-试题版含答案-【两点距离】【字符串替换】【盗梦空间】【素数】

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 &#x1f449;关于作者 专注于Android/Unity和各种游…

关于内存颗粒的地址映射

即便从软件角度&#xff0c;抛开地址译码器讨论内存颗粒中指定位置处的地址&#xff08;DDR中的指定位置的电容&#xff09;也是没有意义的。晶体管没有绝对地址&#xff0c;就如同地理测量中测定位置前需要确定坐标系一样&#xff0c;同一个位置在不同的坐标系中的地址描述可以…

vue-tsc --noEmit导致打包报TS类型错误

&#x1f431; 个人主页&#xff1a;不叫猫先生&#xff0c;公众号&#xff1a;前端舵手 &#x1f64b;‍♂️ 作者简介&#xff1a;2022年度博客之星前端领域TOP 2&#xff0c;前端领域优质作者、阿里云专家博主&#xff0c;专注于前端各领域技术&#xff0c;共同学习共同进步…

TypeScript——泛型

泛型&#xff08;Generics&#xff09;是指在定义函数、接口或类的时候&#xff0c;不预先指定具体的类型&#xff0c;而在使用的时候再指定类型的一种特性。 函数泛型 本来函数参数类型的不同时&#xff0c;要写多个&#xff0c;现在用泛型&#xff0c;只需要使用时传参即可…

吉他如何实现内录or通过转接头和简易声卡连接电脑没有声音怎么办

目录 效果器or智能音箱 电吉他和效果器的连接 效果器和耳机or音箱连接 内录方法 为什么用6.5mm&#xff08;入&#xff09;转3.5mm&#xff08;出&#xff09;转接头内录无声音 整体连接图示 这篇文章我会以通俗的语言为初学者描述如何让电吉他“燃起来”&#xff0c;效果…

Idea项目application.properties配置文件默认GBK,如何设置默认为UTF-8编码

简述&#xff1a;java程序在项目中一般设置都是UTF-8编码格式&#xff0c;但是项目application.properties 文件默认是GBK,需要手工修改默认编码格式 步骤&#xff1a; file->setting->editor->file encodings下&#xff0c;勾选transparent native-to-ascll conver…

亚马逊云科技以用户为中心,持续丰富安全服务和解决方案

AI加持安全&#xff0c;自动化运营成未来趋势 亚马逊云科技始终在云安全领域不断创新探索、深耕发力&#xff0c;随着全球技术的发展而持续迭代安全能力。 当下&#xff0c;以ChatGPT为代表的AIGC成为最出圈的热点&#xff0c;大量的科技巨头纷纷涌入AI赛道&#xff0c;投入了…

森海塞尔重磅推出TC Bars智能音视频一体机, 为中小型协作空间缔造理想解决方案

森海塞尔重磅推出TC Bars智能音视频一体机&#xff0c; 为中小型协作空间缔造理想解决方案 全球音频行业先驱森海塞尔重磅推出首款内置摄像头的可扩展一体化会议设备 德国韦德马克&#xff0c;2023年6月13日——森海塞尔作为先进音频技术的首选&#xff0c;致力于使协作与学习…

Clickhouse物化视图原理和使用详解

前言 ClickHouse广泛用于用户和系统日志查询场景中&#xff0c;主要针对于OLAP场景&#xff0c;为业务方提供稳定高效的查询服务。在业务场景下&#xff0c;数据以不同的格式、途径写入到clickhouse。用传统JOIN方式查询海量数据&#xff0c;通常有如下痛点: 每个查询的代码冗…

RabbitMQ灵活运用,怎么理解五种消息模型

RabbitMQ灵活运用&#xff0c;怎么理解五种消息模型 简介一、AMQP协议二、交换机类型与默认交换机1. 交换机的四种类型2. 默认交换机 三、五种模式速览1. 一对一简单模式2. work模式&#xff08;轮询&#xff09;3. 发布/订阅模式4. 路由模式&#xff08;自称direct模式&#x…