"权限按钮组件"在中大型前端项目中是非常通用的一类功能组件,通常用于根据用户权限动态显示 CRUD 按钮(增删改查)。
下面设计一套:
- ✅ Vue 3 + TypeScript 写法
- ✅ 支持
v-permission或权限数组控制 - ✅ 封装单个 CRUD 按钮
- ✅ 提供组合按钮容器(任意组合增删改查)
- ✅ 支持统一样式、禁用态与事件透传
🧩 一、权限控制思路
假设你有一个权限系统,每个按钮对应一个权限码,例如:
ts
"sys:user:add" // 新增
"sys:user:edit" // 修改
"sys:user:delete" // 删除
"sys:user:view" // 查询
用户登录后,存储在 userStore 中:
ts
userStore.permissions = ['sys:user:view', 'sys:user:edit']
✅ 二、权限按钮指令(v-permission)
创建一个通用权限指令:
ts
// 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);
}
},
};
注册全局指令:
ts
// main.ts
import { permission } from "@/directives/permission";
app.directive("permission", permission);
✅ 三、单个权限按钮组件
vue
<!-- components/AuthButton.vue -->
<template>
<el-button
v-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 组合按钮组件
该组件可以自由组合 "增删改查" 四种按钮。
vue
<!-- components/AuthCrudButtons.vue -->
<template>
<div class="auth-crud-buttons">
<AuthButton
v-if="showAdd"
perm="sys:user:add"
type="primary"
icon="Plus"
label="新增"
@click="$emit('add')"
/>
<AuthButton
v-if="showEdit"
perm="sys:user:edit"
type="warning"
icon="Edit"
label="编辑"
@click="$emit('edit')"
/>
<AuthButton
v-if="showDelete"
perm="sys:user:delete"
type="danger"
icon="Delete"
label="删除"
@click="$emit('delete')"
/>
<AuthButton
v-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>
✅ 五、使用示例
✅ 单个按钮
vue
<AuthButton
perm="sys:user:add"
type="primary"
label="新增"
@click="handleAdd"
/>
若用户无
sys:user:add权限,则按钮不会渲染。
✅ 组合 CRUD 按钮
vue
<AuthCrudButtons
:show-add="true"
:show-edit="true"
:show-delete="true"
:show-view="false"
@add="handleAdd"
@edit="handleEdit"
@delete="handleDelete"
/>
若用户只拥有
sys:user:view和sys:user:edit,则组件内部仅渲染"编辑"按钮。
✅ 六、进阶增强(推荐加上)
可以让 AuthCrudButtons 支持自定义权限码,让它在不同模块通用:
vue
<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">
<AuthButton
v-if="showAdd"
:perm="getPerm('add')"
type="primary"
icon="Plus"
label="新增"
@click="$emit('add')"
/>
<AuthButton
v-if="showEdit"
:perm="getPerm('edit')"
type="warning"
icon="Edit"
label="编辑"
@click="$emit('edit')"
/>
<AuthButton
v-if="showDelete"
:perm="getPerm('delete')"
type="danger"
icon="Delete"
label="删除"
@click="$emit('delete')"
/>
<AuthButton
v-if="showView"
:perm="getPerm('view')"
type="info"
icon="View"
label="查看"
@click="$emit('view')"
/>
</div>
</template>
使用时:
vue
<AuthCrudButtons prefix="sys:user" :show-add="true" :show-delete="true" />
✅ 七、总结
| 组件 | 作用 |
|---|---|
v-permission |
指令级权限控制 |
AuthButton |
单个按钮的权限封装 |
AuthCrudButtons |
CRUD 按钮组合,可自由控制显示与模块前缀 |