最新要闻
- 弘扬绿色健康饮食文化-热闻
- 天天信息:热搜第二!网友月薪5000两年存了8万元:分享7个实用存钱技巧
- 卖一个赚46块!激光雷达首次盈利 禾赛科技:感谢理想 世界时讯
- 实时:清新口气 有效抑菌!纳美亮白牙膏:6支仅14.9元
- 里程碑!小米宣布:MIUI全球月活用户突破6亿
- 环球新资讯:距离月面10米失联!NASA:日本登月失败登月舱残骸或找到
- 世界观点:被曝北约考虑在日设联络处后,岸田宣称日本没有加入北约计划
- 苦等几十年!Windows终于原生支持rar、7z等格式压缩文件了|全球视点
- 车标贴满全身!梅赛德斯-迈巴赫Night Series官图发布:真奢华
- 【全球聚看点】699元 联想YOGA K7机械键盘上架:82键矮轴 真空电镀工艺
- AI网聊10分钟被骗430万 中国互联网协会给出防范建议
- 环球今头条!国内多航司现千元内国际机票 上海直飞日本仅600元
- 西部决赛:掘金淘汰洛杉矶湖人的背后,藏着多少鲜为人知的秘密-热消息
- 安卓不再清后台 OPPO Reno10系列用上16GB大内存:48个月流畅
- Find系列同款!OPPO Reno10 Pro搭载动态光影屏:120Hz高刷
- 视点!不怕别人超越!“比亚迪魔方”储能系统发布:首搭刀片电池
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
全球实时:记录--按钮级别权限怎么控制
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助
最近的面试中有一个面试官问我按钮级别的权限怎么控制,我说直接v-if
啊,他说不够好,我说我们项目中按钮级别的权限控制情况不多,所以v-if
就够了,他说不够通用,最后他对我的评价是做过很多东西,但是都不够深入,好吧,那今天我们就来深入深入。
因为我自己没有相关实践,所以接下来就从这个有16.2k
星星的后台管理系统项目Vue vben admin中看看它是如何做的。
获取权限码
要做权限控制,肯定需要一个code
,无论是权限码还是角色码都可以,一般后端会一次性返回,然后全局存储起来就可以了,Vue vben admin
是在登录成功以后获取并保存到全局的store
中:
(相关资料图)
import { defineStore } from "pinia";export const usePermissionStore = defineStore({ state: () => ({ // 权限代码列表 permCodeList: [], }), getters: { // 获取 getPermCodeList(){ return this.permCodeList; }, }, actions: { // 存储 setPermCodeList(codeList) { this.permCodeList = codeList; }, // 请求权限码 async changePermissionCode() { const codeList = await getPermCode(); this.setPermCodeList(codeList); } }})
接下来它提供了三种按钮级别的权限控制方式,一一来看。
函数方式
使用示例如下:
拥有[20000,2000010]code可见 <script lang="ts"> import { usePermission } from "/@/hooks/web/usePermission"; export default defineComponent({ setup() { const { hasPermission } = usePermission(); return { hasPermission }; }, });</script>
本质上就是通过v-if
,只不过是通过一个统一的权限判断方法hasPermission
:
export function usePermission() { function hasPermission(value, def = true) { // 默认视为有权限 if (!value) { return def; } const allCodeList = permissionStore.getPermCodeList; if (!isArray(value)) { return allCodeList.includes(value); } // intersection是lodash提供的一个方法,用于返回一个所有给定数组都存在的元素组成的数组 return (intersection(value, allCodeList)).length > 0; return true; }}
很简单,从全局store
中获取当前用户的权限码列表,然后判断其中是否存在当前按钮需要的权限码,如果有多个权限码,只要满足其中一个就可以。
组件方式
除了通过函数方式使用,也可以使用组件方式,Vue vben admin
提供了一个Authority
组件,使用示例如下:
<script> import { Authority } from "/@/components/Authority"; import { defineComponent } from "vue"; export default defineComponent({ components: { Authority }, });</script>只有admin角色可见
使用Authority
包裹需要权限控制的按钮即可,该按钮需要的权限码通过value
属性传入,接下来看看Authority
组件的实现。
<script lang="ts"> import { defineComponent } from "vue"; import { usePermission } from "/@/hooks/web/usePermission"; import { getSlot } from "/@/utils/helper/tsxHelper"; export default defineComponent({ name: "Authority", props: { value: { type: [Number, Array, String], default: "", }, }, setup(props, { slots }) { const { hasPermission } = usePermission(); function renderAuth() { const { value } = props; if (!value) { return getSlot(slots); } return hasPermission(value) ? getSlot(slots) : null; } return () => { return renderAuth(); }; }, });</script>
同样还是使用hasPermission
方法,如果当前用户存在按钮需要的权限码时就原封不动渲染Authority
包裹的内容,否则就啥也不渲染。
指令方式
最后一种就是指令方式,使用示例如下:
拥有code ["1000"]权限可见
实现如下:
import { usePermission } from "/@/hooks/web/usePermission";function isAuth(el, binding) { const { hasPermission } = usePermission(); const value = binding.value; if (!value) return; if (!hasPermission(value)) { el.parentNode?.removeChild(el); }}const mounted = (el, binding) => { isAuth(el, binding);};const authDirective = { // 在绑定元素的父组件 // 及他自己的所有子节点都挂载完成后调用 mounted,};// 注册全局指令export function setupPermissionDirective(app) { app.directive("auth", authDirective);}
只定义了一个mounted
钩子,也就是在绑定元素挂载后调用,依旧是使用hasPermission
方法,判断当前用户是否存在通过指令插入的按钮需要的权限码,如果不存在,直接移除绑定的元素。
很明显,Vue vben admin
的实现有两个问题,一是不能动态更改按钮的权限,二是动态更改当前用户的权限也不会生效。
解决第一个问题很简单,因为上述只有删除元素的逻辑,没有加回来的逻辑,那么增加一个updated
钩子:
app.directive("auth", { mounted: (el, binding) => { const value = binding.value if (!value) return if (!hasPermission(value)) { // 挂载的时候没有权限把元素删除 removeEl(el) } }, updated(el, binding) { // 按钮权限码没有变化,不做处理 if (binding.value === binding.oldValue) return // 判断用户本次和上次权限状态是否一样,一样也不用做处理 let oldHasPermission = hasPermission(binding.oldValue) let newHasPermission = hasPermission(binding.value) if (oldHasPermission === newHasPermission) return // 如果变成有权限,那么把元素添加回来 if (newHasPermission) { addEl(el) } else { // 如果变成没有权限,则把元素删除 removeEl(el) } },})const hasPermission = (value) => { return [1, 2, 3].includes(value)}const removeEl = (el) => { // 在绑定元素上存储父级元素 el._parentNode = el.parentNode // 在绑定元素上存储一个注释节点 el._placeholderNode = document.createComment("auth") // 使用注释节点来占位 el.parentNode?.replaceChild(el._placeholderNode, el)}const addEl = (el) => { // 替换掉给自己占位的注释节点 el._parentNode?.replaceChild(el, el._placeholderNode)}
主要就是要把父节点保存起来,不然想再添加回去的时候获取不到原来的父节点,另外删除的时候创建一个注释节点给自己占位,这样下次想要回去能知道自己原来在哪。
第二个问题的原因是修改了用户权限数据,但是不会触发按钮的重新渲染,那么我们就需要想办法能让它触发,这个可以使用watchEffect
方法,我们可以在updated
钩子里通过这个方法将用户权限数据和按钮的更新方法关联起来,这样当用户权限数据改变了,可以自动触发按钮的重新渲染:
import { createApp, reactive, watchEffect } from "vue"const codeList = reactive([1, 2, 3])const hasPermission = (value) => { return codeList.includes(value)}app.directive("auth", { updated(el, binding) { let update = () => { let valueNotChange = binding.value === binding.oldValue let oldHasPermission = hasPermission(binding.oldValue) let newHasPermission = hasPermission(binding.value) let permissionNotChange = oldHasPermission === newHasPermission if (valueNotChange && permissionNotChange) return if (newHasPermission) { addEl(el) } else { removeEl(el) } }; if (el._watchEffect) { update() } else { el._watchEffect = watchEffect(() => { update() }) } },})
将updated
钩子里更新的逻辑提取成一个update
方法,然后第一次更新在watchEffect
中执行,这样用户权限的响应式数据就可以和update
方法关联起来,后续用户权限数据改变了,可以自动触发update
方法的重新运行。
本文转载于:
https://juejin.cn/post/7209648356530896953
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。
关键词:
全球实时:记录--按钮级别权限怎么控制
全球观点:债市日报:5月24日
弘扬绿色健康饮食文化-热闻
天天信息:热搜第二!网友月薪5000两年存了8万元:分享7个实用存钱技巧
卖一个赚46块!激光雷达首次盈利 禾赛科技:感谢理想 世界时讯
实时:清新口气 有效抑菌!纳美亮白牙膏:6支仅14.9元
里程碑!小米宣布:MIUI全球月活用户突破6亿
环球新资讯:距离月面10米失联!NASA:日本登月失败登月舱残骸或找到
未能封送类型,因为嵌入数组实例的长度与布局中声明的长度不匹配 全球微头条
理解JS中的Promise
一步步完整搭建一个图纸管理系统(Django+Vue3)
【MyBatis】saveBatch 性能调优|即时焦点
世界观点:被曝北约考虑在日设联络处后,岸田宣称日本没有加入北约计划
苦等几十年!Windows终于原生支持rar、7z等格式压缩文件了|全球视点
车标贴满全身!梅赛德斯-迈巴赫Night Series官图发布:真奢华
【全球聚看点】699元 联想YOGA K7机械键盘上架:82键矮轴 真空电镀工艺
AI网聊10分钟被骗430万 中国互联网协会给出防范建议
环球今头条!国内多航司现千元内国际机票 上海直飞日本仅600元
西部决赛:掘金淘汰洛杉矶湖人的背后,藏着多少鲜为人知的秘密-热消息
es之增删改查 每日播报
顶象全新金融业务安全方案,亮相亚太银行数字化峰会
Java开启异步的两种方式
Python文件读写、StringIO和BytesIO_每日速看
动态:Ruby教程_编程入门自学教程_菜鸟教程-免费教程分享
【环球新要闻】【新华500】新华500指数(989001)24日下跌1.28%
安卓不再清后台 OPPO Reno10系列用上16GB大内存:48个月流畅
Find系列同款!OPPO Reno10 Pro搭载动态光影屏:120Hz高刷
视点!不怕别人超越!“比亚迪魔方”储能系统发布:首搭刀片电池
环球新消息丨349元 OPPO Enco R2耳机发布:Hi-Fi级处理芯片
支付宝提醒“学生账户升级”骗局:没有学生/成人账户概念!
焦点快播:Spring Boot 我随手封装了一个万能的 Excel 导出工具,传什么都能导出!
火山引擎DataLeap联合DataFun发布《数据治理知识地图》_世界新消息
当前要闻:推荐一个AI导航网站 - 收录的都是热门AI工具
社区工作者感受垃圾分类处理全过程
北京西京医院杨博华_北京西京医院
64核CPU、显卡三连冠 AMD超算屠榜:唯一一台百亿亿次
国产SSD卷疯了!梵想S500 Pro 2TB只要409元 观天下
最轻薄潜望手机!OPPO Reno10 Pro+亮相
当前关注:搭载4.0L水平对置发动机 300万的保时捷中国开卖:但不能上路
淮北建投20亿元公司债将付息 利率6.30%
springboot~mybatis-plus的DynamicTableNameInnerInterceptor实现分表
用上3.0T直六发动机!马自达旗舰CX-90现身:今年内国产_天天看热讯
今日播报!Win11最新版发布:性能更好更丝滑
粤港澳大湾区首个京粤产业协作中心挂牌并落户广州黄埔 快播报
苹果WWDC23终极“剧透”:iOS 17登场 首款头显万众期待 天天精选
天天热点评!《原神》3.7版本正式上线!原神首个卡牌赛事登场
99包邮手慢无!匹克路威篮球鞋2折清仓(门店469元)
脾气真大!一特斯拉插队未遂现场报复:直接加速撞车 全球快看
甄子丹出演苹果广告:叶师傅 切他中路!|当前焦点
焦点播报:“五一”假期出行,伴随着哪些风险
全网最全的编程电子书大合集,超千本打包下载
求求你,不要再把ER图和数据库模型图搞混了好嘛?
【一步步开发AI运动小程序】六、人体骨骼图绘制|聚焦
全球观点:云图说丨初识商标注册服务
切辣椒手很辣该怎么办_切辣椒手辣要几个小时消失
焦点速讯:《街霸6》将迎合新一代玩家:隆、肯和春丽等老角色将被取代
今日精选:女孩减肥去世 体重仅24.8公斤!科普神经性厌食危害
“BOSS直聘崩了”登上热搜 公司回应:PC端异常 已紧急修复
电竞首次入赛!杭州亚运会《DOTA2》国家集训队名单出炉:共27人
今日关注:轻微交通事故APP快处 全国首批36城上线!附操作方法
微软重磅宣布!Windows 的“ AI 时刻”来了_环球新消息
【解决方法】SecureCRT远程工具无法show命令无法使用管道符完成中文过滤检索
Apache Hudi 在袋鼠云数据湖平台的设计与实践
CloudQuery v2.0.0 发布 | 新增数据保护、数据变更、连接管理等功能_环球观点
动态:JavaScript基础语法之 || 和 ?? 的踩坑记录
里夫斯:我在发声上做得不如詹眉 但高的篮球IQ会帮我提高领导力 世界微资讯
昆明国资委:“昆明银行口专家路演要点”和《昆明城投专家会议纪要》不实-焦点热门
微动态丨吉利也来“围攻”比亚迪 银河L7上市定档:1.5T插混能跑1300km
官网不停运!亚马逊中国回应7月关闭应用商店:不影响业务运营 天天快播报
迎来重磅更新!Win11文件管理器界面UI将整体重做
低价游太空梦破碎!维珍轨道破产 三大航空公司瓜分其资产|今日快看
双摄像头一览无余!萤石Y3000FVX极光人脸视频锁图赏|世界快资讯
【世界播资讯】现场直击|凯瑞特亮相CTT Expo 2023,热度飙升,实力圈粉
焦点讯息:sipp重放rtp数据测试FreeSWITCH
Algorithm_01--C#递归算法02 每日速看
HTML中的attribute 和 property
世界快资讯:Wi-Fi 6都没玩明白 怎么就惦记上Wi-Fi 7了?
今日关注:马斯克:已确定特斯拉接班人、自己有意外他将接管公司
速递!星巴克家享黑咖啡2.5元/杯大促 原价15元
世界微动态丨明天发布!小米Civi 3首发天玑8200-Ultra:能效、影像增强
千呼万唤始出来!微软官宣Win11任务栏不合并将回归
农发行广西区分行与东兰县签署战略合作协议
苹果MR或将推出 “果链”企业频受调研_环球快消息
骆仁童老师主讲《数字经济下电力业转型》课程 | 河北某地热电企业-2023年中高层管理人员培训班(二期)
80年代曾风靡全球 乐高为“吃豆人”游戏打造了一款街机 还能玩 焦点快看
世界热点评!新能源汽车高歌猛进 5月销量预计大增60% 渗透率超1/3
乌冬面里吃出活青蛙 日本连锁店鞠躬道歉:网友看完大呼恶心|世界热闻
越南打工人不加班逼急中国老板 不为钱放弃生活:全球各国每日工作时间一览-世界快讯
美国债务上限谈判未破僵局 避险美债再获追捧
为什么说人民币汇率不会大起大落-全球快播报
茶叶的故乡是哪里 茶的故乡是哪儿 天天报资讯
史诗级更新!特斯拉2023.12.9 OTA推送:强制单踏板成历史_天天短讯
Win10已死!微软发布Windows 11大更新:引入ChatGPT、升级巨大
《英雄联盟》衍生游戏!《聚点危机:英雄联盟外传》开售:GTX 460爽玩
全面实施国六B 这类汽车将禁止销售 会大幅降价吗?-今日播报
芦荟胶去红血丝效果好吗(芦荟胶对红血丝有效果吗)
焦点!5899元起 索尼新一代超广角变焦Vlog相机ZV-1 II发布
MarkDown的使用(一)
全球动态:宁波海达控股集团有限公司
苹果遭殃!逃税近千亿元-世界要闻