Vue 自定义指令实现组件级精准的权限控制 v-permission

作者:Administrator 发布时间: 2025-12-16 阅读量:6 评论数:0
<template>
  <div class="permission-page">
    <!-- 同时需要权限和角色 -->
    <el-button v-permission="[['order:edit'], ['admin']]">管理员编辑</el-button>
    <!-- 只需要权限 -->
    <el-button v-permission="'finance:approve'">财务审批</el-button>
    <!-- 权限或角色满足其一 -->
    <el-button v-permission="'user'">订单查看</el-button>
     <!-- 同时需要权限和角色 -->
    <el-button v-permission="[['order:view'], ['user']]">审计查看</el-button>
  </div>
</template>

<script setup>
import { onMounted, onBeforeMount, ref } from "vue";
import { usePermissionStore } from "@/stores/permission";

onBeforeMount(() => {
  setAuthINfo();
});

const setAuthINfo = async () => {
  // 模拟获取用户权限信息
  const permissionStore = usePermissionStore();
  const permissioninfo = {
    roles: ["user", "admin"],
    permissions: [
      "order:view",
      "order:edit",
      "order:export",
      "payment:approve",
      "finance:approve",
    ],
  };
  // 设置权限信息到权限仓库
  permissionStore.setAuthInfo({
    roles: permissioninfo.roles,
    permissions: permissioninfo.permissions,
  });
};
</script>

<style lang="less" scoped>
.permission-page {
  width: 1200px;
  margin: 0 auto;
}
</style>

自定义指令实现

import { usePermissionStore } from '@/stores/permission';

const permissionDirective = {
  mounted(el, binding) {
    const store = usePermissionStore();
    const { value } = binding;
    
    if (!value) return;
    
    if (Array.isArray(value)) {
      // 数组:同时需要权限和角色
      const permissions = value[0];
      const roles = value[1];
      const hasPerm = store.hasPermission(permissions);
      const hasRole = store.hasRole(roles);
      if (!(hasPerm && hasRole)) {
        el.parentNode?.removeChild(el);
      }
    } else {
      // 字符串:权限或角色满足其一
      const hasPerm = store.hasPermission(value);
      const hasRole = store.hasRole(value);
      if (!(hasPerm || hasRole)) {
        el.parentNode?.removeChild(el);
      }
    }
  }
};

export function setupPermissionDirective(app) {
  app.directive('permission', permissionDirective);
}

pinia 实现

import { defineStore } from 'pinia';

export const usePermissionStore = defineStore('permission', {
  state: () => ({
    roles: [] ,
    permissions: []
  }),
  actions: {
    setAuthInfo(payload) {
      this.roles = payload.roles;
      this.permissions = payload.permissions;
    }
  },
  getters: {
    // 是否有权限
    hasPermission: (state) => (value) => {
      const required = Array.isArray(value) ? value : [value];
      return required.some(perm => state.permissions.includes(perm));
    },
    // 角色是一个数组,传入一个数组,判断是否有权限
    hasRole: (state) => (value) => {
      const required = Array.isArray(value) ? value : [value];
      return required.some(role => state.roles.includes(role));
    }
  }
});

评论