vue权限控制的想法

前言

最近做到了一个权限控制的功能。在这个功能中看到了这个功能的写法,了解到了这个权限控制的功能,也引发了思考。除了 v-if ,还有没有更好的,更直观的,更全局的写法呢?带着这个问题,我们先来看一下,这个权限数据的来源。

权限来源

获取数据的方法也很简单,就是后台接口请求数据。后端在登录后一次性返回所有的权限数据,然后全局 localStorage 或者 store 存储起来。如果发生了修改就可以及时的通知到全局,在使用获取的时候也方便快捷。代码如下:

import { defineStore } from 'pinia'
// 声明,初始化
const defaultState = {permissions: {}, // 权限列表
}// 设置state,存储
function setData(obj) {Object.keys(obj).forEach((key) => {state[key] = obj[key]})// 每次改动更新缓存localStorage.setItem(LOCAL_STORAGE_NAME, JSON.stringify(toRaw(state)))
}// 请求权限码
async function getPermissionList() {const res = await ajaxStore.common.getPermissionList()if (res.data?.code === '0') {const arr = res.data?.data ?? []const obj = {}arr.forEach((item) => (obj[item.permissionCode] = item.permissionName))// 全局存储setData({ permissions: obj })return state.permissions} else {return null}
}

获取到数据以后,就可以来思考怎么使用这些数据。目前,所知的有3种权限控制方式,下面我们一个一个的来看。

三种方法

1. 函数方式

这是我们最先想到的方法,也是最常用的方法。代码如下:

<template><div><Tabs :data="tabConfigs"></Tabs><NoPower v-if="!(tabConfigs && tabConfigs.length)"></NoPower></div>
</template>
<script setup name="realestateWarning">
// 获取 permissions 数据
import useUser from '@/store/user'
// 获取所有的菜单
import { realestateWarningTabs } from '@/const/menu'const userInfo = useUser()
// 过滤tab权限
const tabConfigs = computed(() => {const { permissions } = userInfo ?? {}return (realestateWarningTabs.filter((item) => {item.label = item.textreturn permissions[item.permissionCode]}) ?? [])
})
</script>

本质就是使用 一个 tabConfigs 来筛选需要显示哪些 tab,其中操作是从全局 store 中获取当前用户的权限码列表,然后判断其中是否存在当前需要的权限码,如果有对应的权限码,就加进来。

2. 组件方式

我们可以单独写一个组件,在组件内部进行权限的控制操作,主要是通过插槽的形式把内部需要展示的组件引入进来,在需要加权限的地方进行组件的引入,组件内部的逻辑和函数方式基本无异。这样就可以统一管理权限了,使用起来也比较方便。代码如下:

<template><div><Permission :value="AAAAAA"><AAAAAA/></Permission><Permission :value="BBBBBB"><BBBBBB/></Permission><Permission :value="CCCCCC"><CCCCCC/></Permission></div>
</template>
<script>import { Permission } from './Permission';
</script>
<script>
// 获取 permissions 数据
import useUser from '@/store/user'
// 获取所有的菜单
import { realestateWarningTabs } from '@/const/menu'export default defineComponent({props: {value: {type: [Number, Array, String],default: '',},},setup(props, { slots }) {const userInfo = useUser()const { permissions } = userInfo ?? {}const { hasPermission } = usePermission();function renderAuth() {const { value } = props;if (!value) {return getSlot(slots);}return permissions[value] ? getSlot(slots) : null;}return () => {return renderAuth();};},
});
</script>

3. 指令方式

指令方式就是自己写个指令,在需要的组件上使用指令就行了。如下:

引用:

<template><div><AAAAAA v-permission="AAAAAA"/><BBBBBB v-permission="BBBBBB"/><CCCCCC v-permission="CCCCCC"/></div>
</template>

编写指令:

import { createApp, reactive, watchEffect } from "vue"
const codeList = reactive([1, 2, 3])const hasPermission = (value) => {return codeList.includes(value)
}app.directive("permission", {updated(el, binding) {let update = () => {let valueNotChange = binding.value === binding.oldValuelet oldHasPermission = hasPermission(binding.oldValue)let newHasPermission = hasPermission(binding.value)let permissionNotChange = oldHasPermission === newHasPermissionif (valueNotChange && permissionNotChange) returnif (newHasPermission) {addEl(el)} else {removeEl(el)}};if (el._watchEffect) {update()} else {el._watchEffect = watchEffect(() => {update()})}},
})

在绑定元素挂载后调用,使用 permissions 判断当前用户是否存在通过指令插入的按钮需要的权限码,如果不存在,直接移除绑定的元素。

在实际的开发中也会有其他的控制方式,在各种论坛中也看到了,使用装饰器来做的,其实不管怎么做,都是为了抽离业务逻辑,是我们用起来跟简单为目的。

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

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

相关文章

openGauss学习笔记-55 openGauss 高级特性-全密态数据库

文章目录 openGauss学习笔记-55 openGauss 高级特性-全密态数据库55.1 连接全密态数据库55.2 创建用户密钥55.3 创建加密表55.4 向加密表插入数据并进行查询 openGauss学习笔记-55 openGauss 高级特性-全密态数据库 全密态数据库意在解决数据全生命周期的隐私保护问题&#xf…

Java LinkedList

简介 链表&#xff08;Linked list&#xff09;是一种常见的基础数据结构&#xff0c;是一种线性表&#xff0c;但是并不会按线性的顺序存储数据&#xff0c;而是在每一个节点里存到下一个节点的地址。 链表可分为单向链表和双向链表。 在Java程序设计语言中&#xff0c;所有…

RabbtiMQ的安装与在Springboot中的使用!!!

一、安装Erlang与Rabbitmq 安装教程本教程是在centos8下试验的&#xff0c;其实linux系统的都差不多RabbitMQ官方&#xff1a;Messaging that just works — RabbitMQRabbitMQ是开源AMQP实现&#xff0c;服务器端用Erlang语言编写&#xff0c;Python、Ruby、 NET、Java、JMS、c…

机器学习笔记:轨迹驻留点 staypoint

1 定义 在轨迹数据分析中&#xff0c;"停留点"&#xff08;Staypoint&#xff09;是一个非常关键的概念&#xff0c;它反映了个体或物体在某一地点的停留行为。通常&#xff0c;在一段时间内&#xff0c;如果一个人或物体在一个较小的地理区域内的移动距离低于某个阈…

git查询和设置用户名及邮箱

由于从原来的旧机子换到了新机子&#xff0c;很多东西都需要重新来&#xff0c;包括git&#xff0c;在vscode终端中安装了git&#xff0c;也ssh连到了远程的仓库。以为一切都ok了&#xff0c;在本地完成任务要推到远程时&#xff0c;告诉我说远程不知道我的身份&#xff0c;需要…

攻防世界-WEB-ics-05

打开靶机 只有设备维护中心可以点开 点标签得到新的url pageindex 想到文件包含漏洞&#xff08;URL中出现path、dir、file、pag、page、archive、p、eng、语言文件等相关关键字眼 利用php伪协议查看源码 出现一段base64源码&#xff0c;进行转码得出源码 ?pagephp://filter…

OpenCV(十七):拉普拉斯图像金字塔

1.拉普拉斯图像金字塔原理 拉普拉斯图像金字塔是一种多尺度图像表示方法&#xff0c;通过对高斯金字塔进行差分运算得到。它能够提供图像在不同尺度上的细节信息&#xff0c;常用于图像处理任务如图像增强、边缘检测等。 下面是拉普拉斯图像金字塔的原理和步骤&#xff1a; 构…

pytorch-构建卷积神经网络

构建卷积神经网络 卷积网络中的输入和层与传统神经网络有些区别&#xff0c;需重新设计&#xff0c;训练模块基本一致 import torch import torch.nn as nn import torch.optim as optim import torch.nn.functional as F from torchvision import datasets,transforms impor…

Agisoft Metashape相机标定笔记

Lens Calibration(镜头标定) 使用Metashape进行自动相机标定是可能的。Metashape使用LCD显示屏作为标定目标&#xff08;可选&#xff1a;使用打印的棋盘格图案&#xff0c;但需保证它是平坦的且单元格是正方形&#xff09;。 相机标定步骤支持全相机标定矩阵的估计&#xff…

pg 配置 -- chatGPT

问&#xff1a;pg 配置不生成 log gpt: 如果你想在 PostgreSQL 中禁用日志记录&#xff08;不生成日志&#xff09;&#xff0c;你可以采取以下步骤&#xff1a; **1. 编辑 PostgreSQL 配置文件&#xff1a;** 打开 PostgreSQL 的配置文件&#xff0c;通常位于 /etc/postgr…

蓝桥杯打卡Day3

文章目录 吃糖果递推数列 一、吃糖果IO链接 本题思路:本题题意就是斐波那契数列&#xff01; #include <bits/stdc.h>typedef uint64_t i64;i64 f(i64 n) {if(n1) return 1;if(n2) return 2;return f(n-1)f(n-2); }signed main() {std::ios::sync_with_stdio(false);s…

kubernetes——ingress

简介 ingress: 是k8s内部的一个资源对象ingress controller -> ingress控制器&#xff1a; 是k8s里启动的一个pod&#xff0c;运行的是nginx的镜像&#xff0c;实现k8s内部的service&#xff08;ClusterIP类型&#xff09;的负载均衡 ingress 和ingress controller 的关…

docker容器运行成功但无法访问,原因分析及对应解决方案(最新,以Tomcat为例,亲测有效)

原因分析&#xff1a; 是否能访问当运行docker容器虚拟机&#xff08;主机&#xff09;地址 虚拟机对应的端口号是否开启或者防墙是否关闭 端口映射是否正确&#xff08;这个是我遇到的&#xff09; tomcat下载的是最新版&#xff0c;docker运行后里面是没有东西的&am…

大厂密集背后,折叠屏市场“暗战”已起

在经过长达10余年的高速增长之后&#xff0c;智能手机行业在过去两年出现了显著的“颓势”&#xff0c;高中低端各个不同市场的分化也越发明显&#xff0c;但新兴的折叠屏市场却滑出了一条“向上”的曲线&#xff0c;引发市场关注。它从形态上颠覆了用户的认知&#xff0c;给市…

单片机-蜂鸣器

简介 蜂鸣器是一种一体化结构的电子讯响器&#xff0c;采用直流电压供电 蜂鸣器主要分为 压电式蜂鸣器 和 电磁式蜂鸣器 两 种类型。 压电式蜂鸣器 主要由多谐振荡器、压电蜂鸣片、阻抗匹配器及共鸣箱、外壳等组成。多谐振荡器由晶体管或集成电路构成&#xff0c;当接通电源后&…

Java ArrayList

简介 ArrayList类示一个可以动态修改的数组&#xff0c;与普通数组的区别是它没有固定大小的限制&#xff0c;可以添加和删除元素。 适用情况&#xff1a; 频繁的访问列表中的某一元素只需要在列表末尾进行添加和删除某些元素 实例 ArrayList 是一个数组队列&#xff0c;提…

PostgreSQL本地化

本地化的概念 本地化的目的是支持不同国家、地区的语言特性、规则。比如拥有本地化支持后&#xff0c;可以使用支持汉语、法语、日语等等的字符集。除了字符集以外&#xff0c;还有字符排序规则和其他语言相关规则的支持&#xff0c;例如我们知道(‘a’,‘b’)该如何排序&…

移动安全测试框架-MobSF WINDOWS 环境搭建

安装python python-3.11.5-amd64.exe 安装Win64OpenSSL-3_1_2.exe 安装VisualStudioSetup.exe github下载安装包 https://github.com/MobSF/Mobile-Security-Framework-MobSF/archive/refs/heads/master.zip GitHub - MobSF/Mobile-Security-Framework-MobSF: Mobile Secur…

亲测可用的1688商品详情API和关键字搜索API,需要自取!

引言 1688是中国最大的B2B电商平台之一&#xff0c;拥有众多的供应商和商品。为了方便用户查找需要的商品&#xff0c;1688提供了关键词搜索商品的API接口。通过该接口开发者可以在自己的系统中调用平台上的数据和功能&#xff0c;例如获取商品信息、下单等操作1。 1688平台提…

mysql 数据库面试题整理

Mysql 中 MyISAM 和 InnoDB 的区别 1、InnoDB 支持事务MyISAM 不支持 2、InnoDB 支持外键MyISAM 不支持 3、InnoDB 是聚集索引&#xff0c;MyISAM 是非聚集索引 4、InnoDB 不保存表的具体行数 5、InnoDB 最小的锁粒度是行锁&#xff0c;MyISAM是表锁 mysql中有就更新&#xf…