vue3 按钮权限组件

181 阅读2分钟

背景:管理端 PC-页面操作按钮,根据接口返回的权限数据动态渲染按钮。

目的:为了给自己做一个记录方便下次复制粘贴。

实现方式:

  1. 全局指令(直接操作DOM的删除或者插入)
  2. 数据拦截,根据后端接口返回的数据,进行增加新增字段状态或者使用 computed 计算属性实现。
  3. 封装公共权限按钮动态渲染组件
  • 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>