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

vue3-封装权限按钮组件和自定义指令

“权限按钮组件”在中大型前端项目中是非常通用的一类功能组件,通常用于根据用户权限动态显示 CRUD 按钮(增删改查)。

下面设计一套:

  • ✅ Vue 3 + TypeScript 写法
  • ✅ 支持 v-permission 或权限数组控制
  • ✅ 封装单个 CRUD 按钮
  • ✅ 提供组合按钮容器(任意组合增删改查)
  • ✅ 支持统一样式、禁用态与事件透传

🧩 一、权限控制思路

假设你有一个权限系统,每个按钮对应一个权限码,例如:

"sys:user:add"      // 新增
"sys:user:edit"     // 修改
"sys:user:delete"   // 删除
"sys:user:view"     // 查询

用户登录后,存储在 userStore 中:

userStore.permissions = ['sys:user:view', 'sys:user:edit']

✅ 二、权限按钮指令(v-permission)

创建一个通用权限指令:

// directives/permission.ts
import { Directive } from "vue";
import { useUserStore } from "@/store/modules/user";export const permission: Directive = {mounted(el, binding) {const userStore = useUserStore();const requiredPerm = binding.value as string;if (!userStore.permissions.includes(requiredPerm)) {el.parentNode && el.parentNode.removeChild(el);}},
};

注册全局指令:

// main.ts
import { permission } from "@/directives/permission";
app.directive("permission", permission);

✅ 三、单个权限按钮组件

<!-- components/AuthButton.vue -->
<template><el-buttonv-if="hasPermission":type="type":icon="icon":disabled="disabled"@click="onClick"><slot>{{ label }}</slot></el-button>
</template><script setup lang="ts">
import { computed } from "vue";
import { useUserStore } from "@/store/modules/user";interface Props {/** 权限码,例如 sys:user:add */perm: string;/** 按钮文字 */label?: string;/** Element Plus 按钮类型 */type?: string;/** 图标 */icon?: string;/** 是否禁用 */disabled?: boolean;
}const props = defineProps<Props>();
const emit = defineEmits(["click"]);const userStore = useUserStore();// 权限校验
const hasPermission = computed(() =>userStore.permissions.includes(props.perm)
);const onClick = () => {emit("click");
};
</script>

✅ 四、CRUD 组合按钮组件

该组件可以自由组合 “增删改查” 四种按钮。

<!-- components/AuthCrudButtons.vue -->
<template><div class="auth-crud-buttons"><AuthButtonv-if="showAdd"perm="sys:user:add"type="primary"icon="Plus"label="新增"@click="$emit('add')"/><AuthButtonv-if="showEdit"perm="sys:user:edit"type="warning"icon="Edit"label="编辑"@click="$emit('edit')"/><AuthButtonv-if="showDelete"perm="sys:user:delete"type="danger"icon="Delete"label="删除"@click="$emit('delete')"/><AuthButtonv-if="showView"perm="sys:user:view"type="info"icon="View"label="查看"@click="$emit('view')"/></div>
</template><script setup lang="ts">
import AuthButton from "./AuthButton.vue";interface Props {/** 是否显示新增按钮 */showAdd?: boolean;/** 是否显示编辑按钮 */showEdit?: boolean;/** 是否显示删除按钮 */showDelete?: boolean;/** 是否显示查看按钮 */showView?: boolean;
}defineProps<Props>();
defineEmits(["add", "edit", "delete", "view"]);
</script><style scoped>
.auth-crud-buttons {display: flex;gap: 8px;
}
</style>

✅ 五、使用示例

✅ 单个按钮

<AuthButtonperm="sys:user:add"type="primary"label="新增"@click="handleAdd"
/>

若用户无 sys:user:add 权限,则按钮不会渲染。


✅ 组合 CRUD 按钮

<AuthCrudButtons:show-add="true":show-edit="true":show-delete="true":show-view="false"@add="handleAdd"@edit="handleEdit"@delete="handleDelete"
/>

若用户只拥有 sys:user:viewsys:user:edit,则组件内部仅渲染“编辑”按钮。


✅ 六、进阶增强(推荐加上)

可以让 AuthCrudButtons 支持自定义权限码,让它在不同模块通用:

<script setup lang="ts">
import AuthButton from "./AuthButton.vue";interface Props {prefix?: string; // 例如 'sys:user'showAdd?: boolean;showEdit?: boolean;showDelete?: boolean;showView?: boolean;
}const props = defineProps<Props>();
defineEmits(["add", "edit", "delete", "view"]);const getPerm = (suffix: string) => `${props.prefix}:${suffix}`;
</script><template><div class="auth-crud-buttons"><AuthButtonv-if="showAdd":perm="getPerm('add')"type="primary"icon="Plus"label="新增"@click="$emit('add')"/><AuthButtonv-if="showEdit":perm="getPerm('edit')"type="warning"icon="Edit"label="编辑"@click="$emit('edit')"/><AuthButtonv-if="showDelete":perm="getPerm('delete')"type="danger"icon="Delete"label="删除"@click="$emit('delete')"/><AuthButtonv-if="showView":perm="getPerm('view')"type="info"icon="View"label="查看"@click="$emit('view')"/></div>
</template>

使用时:

<AuthCrudButtons prefix="sys:user" :show-add="true" :show-delete="true" />

✅ 七、总结

组件作用
v-permission指令级权限控制
AuthButton单个按钮的权限封装
AuthCrudButtonsCRUD 按钮组合,可自由控制显示与模块前缀
http://www.dtcms.com/a/613397.html

相关文章:

  • 物联网定位技术实验报告|实验一 Wi-Fi指纹定位
  • 标签的ref属性
  • 网站站内的seo怎么做拍卖网站建设需求
  • 微服务即时通讯系统(服务端)——消息转发微服务设计与实现详解(5)
  • 抽象工厂模式在智慧蔬菜大棚物联网系统中的应用
  • 新建站点的步骤网站建设工具的公司
  • 【微服务】【Nacos 3】 ① 深度解析:架构演进、核心组件与源码剖析
  • Rust赋能Android蓝牙协议栈:从C++到安全高效的重构之路
  • 网站 建设 原则wordpress入门教程8
  • Wordpress如何选择适合外贸的模板主题?
  • 整体设计 全面梳理复盘 之38 3+1 工具套件(思维工具为根)设计共识暨 DevOps 融合落地路径
  • Goer-Docker系列-1-管理工具
  • 阿里云CentOS环境下Docker Compose详细使用教程
  • Windows 下 Docker Desktop 快速入门与镜像管理
  • 破解跨境数据传输瓶颈:中国德国高速跨境组网专线与本地化 IP 的协同策略
  • SpringCloud:Eureka和负载均衡
  • GSV6127D#ACP#高性能 Type-C/DisplayPort 1.4 中继器与双向 MIPI/LVDS 混合转换器
  • jquery做网站浏览量做竞价的网站做优化有效果吗
  • 交互式网站app商务网站建设期末考试
  • IoTSharp前端VUE采用npm run build编译提示require() of ES Module 出错
  • 高级IO-poll
  • 在JavaScript中,JavaScript 对象和 JSON 字符串互相转换
  • css之弹性盒子属性2
  • [LivePortrait] docs | Gradio用户界面
  • 基于C#+avalonia ui实现的跨平台点胶机灌胶监控控制上位机软件
  • 【三维编辑】DREAMCATALYST:平衡可编辑性和ID的快速高效3D编辑
  • SemanticVLA:面向高效机器人操作的语义对齐剪枝与增强方法
  • 晋城市住建设局网站茂名公司网站设计
  • 太原做响应式网站软件开发公司厂家有哪些
  • 40_FastMCP 2.x 中文文档之FastMCP客户端认证:OAuth 身份验证详解