背景:管理端 PC-页面操作按钮,根据接口返回的权限数据动态渲染按钮。
目的:为了给自己做一个记录方便下次复制粘贴。
实现方式:
- 全局指令(直接操作DOM的删除或者插入)
- 数据拦截,根据后端接口返回的数据,进行增加新增字段状态或者使用 computed 计算属性实现。
- 封装公共权限按钮动态渲染组件
- 1、实现方式由于是直接操作 DOM 会引起回流;并且有时候在获取权限数据时不能在第一时间得到数据;会初始化vue组件的多个生命周期太过于浪费(个人觉得这种太过于普通)
- 2、计算属性需要依赖响应式数据,会导致多余的依赖追踪,而且可能需要将一些状态提升(提升的目的是为了更方便的传递给子组件使用)
- 3、不直接操作 DOM,也不提前渲染一次,直接通过数据渲染所需要的按钮。
组件代码
<template>
<div class="permission-buttons">
<a-button
v-for="(btn, index) in filteredButtons"
:key="index"
v-bind="btn.buttonProps"
v-on="btn.events || {}"
>
{{ btn.text }}
</a-button>
</div>
</template>
<script setup lang="ts">
import { computed, inject } from 'vue';
import { Button } from 'ant-design-vue'; // 导入 Ant Design Vue 的 Button 组件(实际使用时需安装 ant-design-vue)
// 定义 props 类型
interface ButtonConfig {
buttonProps?: Record<string, any>; // 支持 a-button 的所有 props,如 type, size, disabled 等
events?: Record<string, Function>; // 事件对象,如 { click: () => console.log('clicked') }
text: string; // 按钮文本(使用 default slot)
permission?: string; // 可选:权限键,如果提供则检查是否在权限列表中
condition?: (permissions: string[]) => boolean; // 可选:自定义条件函数,接收权限列表,返回 boolean
}
const props = defineProps<{
buttons: ButtonConfig[];
}>();
// 通过 inject 获取权限列表(假设为字符串数组)
const buttonPermission = inject<string[]>('buttonPermission', []);
// 计算过滤后的按钮列表
const filteredButtons = computed(() => {
return props.buttons.filter((btn) => {
if (btn.condition) {
// 优先使用自定义条件函数
return btn.condition(buttonPermission);
} else if (btn.permission) {
// 默认检查 permission 是否在列表中
return buttonPermission.includes(btn.permission);
}
// 如果都没有,则始终显示
return true;
});
});
</script>
<style scoped>
.permission-buttons {
display: flex;
gap: 10px; /* 按钮间距,可根据需要调整 */
}
</style>
示例
<template>
<PermissionButtons :buttons="buttonList" />
</template>
<script setup lang="ts">
import { provide } from 'vue';
import PermissionButtons from './PermissionButtons.vue';
// 提供权限列表
provide('buttonPermission', ['add', 'edit']);
// 定义按钮配置列表
const buttonList = [
{
text: '添加',
buttonProps: { type: 'primary' },
events: { click: () => console.log('添加操作') },
permission: 'add' // 默认检查权限
},
{
text: '编辑',
buttonProps: { type: 'default' },
events: { click: () => console.log('编辑操作') },
condition: (perms) => perms.includes('edit') && someOtherCondition() // 自定义条件
},
{
text: '删除',
buttonProps: { danger: true },
events: { click: () => console.log('删除操作') },
// 无 permission 或 condition,始终显示
}
];
</script>