Skip to content

vue3自定义权限指令v-permission

约 947 字大约 3 分钟

vue3权限

2025-06-23

在 Vue3 + TypeScript 项目中,可以通过自定义指令来控制元素的显示与隐藏,实现权限管理功能。本文将详细介绍如何编写一个 v-permission 指令来根据用户权限动态控制元素的渲染。


功能概述

v-permission 是一个自定义指令,作用如下:

  1. 传入一个权限数组,例如 ['OrderList']
  2. 从 Vuex 中获取用户拥有的权限列表。
  3. 如果用户没有指定权限,则从 DOM 中移除对应元素。
  4. 支持动态更新,通过 updated 钩子重新检查权限。

实现步骤

1. 新建 directives/permission.ts

在项目的 directives 目录下新建 permission.ts,内容如下:

import { App, DirectiveBinding } from "vue";
import store from "@/store";

// 判断是否有权限
const hasPermission = (value: Array<string>, el: Element) => {
  // 检查是否配置了权限参数
  if (!Array.isArray(value) || value.length === 0) {
    throw new Error(`v-permission 需要配置权限,例如 v-permission="['xxx']"`);
  }

  // 获取用户权限
  const ruleNames: Array<string> = store.getters["menu/getRuleNames"] || [];
  if (!Array.isArray(ruleNames)) {
    console.warn(
      '权限数据 "menu/getRuleNames" 格式不正确,请检查 store 配置。'
    );
    return;
  }

  // 判断是否有权限
  const hasAuth = value.some((val) => ruleNames.includes(val));
  if (!hasAuth && el.parentNode) {
    el.parentNode.removeChild(el); // 移除元素
  }
  return hasAuth;
};

export default {
  install(app: App) {
    app.directive("permission", {
      mounted(el: Element, binding: DirectiveBinding) {
        hasPermission(binding.value, el);
      },
      updated(el: Element, binding: DirectiveBinding) {
        hasPermission(binding.value, el);
      },
    });
  },
};

功能说明

  • mounted 钩子:元素挂载时检查权限,如果没有权限,移除元素。
  • updated 钩子:元素或绑定值更新时重新检查权限。
  • 错误提示:当传入的值不正确时,抛出错误或给出警告。
  • store.getters['menu/getRuleNames'] :假设从 Vuex 中获取用户权限列表,返回一个字符串数组。

2. 在 main.ts 中引入指令

main.ts 文件中注册该指令:

import { createApp } from "vue";
import App from "./App.vue";
import store from "@/store";
import permission from "@/directives/permission";

const app = createApp(App);
app.use(store);
app.use(permission); // 注册自定义指令
app.mount("#app");

3. 使用 v-permission 指令

在模板中使用 v-permission 指令,传入权限数组:

<template>
  <div>
    <!-- 用户拥有 'OrderList'权限时显示 -->
    <button v-permission="['OrderList']">有权限的按钮</button>

    <!-- 仅管理员权限时显示 -->
    <div v-permission="['admin']">仅管理员可见内容</div>
  </div>
</template>

权限数据说明

假设 store.getters['menu/getRuleNames'] 返回如下权限数组:

['OrderList', 'admin', 'user:read']
  • 如果传入 ['admin'],当前用户拥有该权限,则元素显示。
  • 如果传入 ['user:write'],当前用户没有该权限,则元素被移除

完整流程回顾

  1. 定义 permission 指令:判断权限并移除无权限的元素。
  2. 注册指令:在 main.ts 中注册全局指令。
  3. 使用指令:在模板中使用 v-permission,传入所需权限数组。
  4. 支持动态更新:元素更新时会重新检查权限。

注意事项

  1. store.getters 配置:确保权限数据正确配置在 Vuex 中,并返回一个数组格式。
  2. 传参校验v-permission 绑定的值必须是数组,否则会抛出错误。
  3. 动态权限变化:如果权限列表动态更新,需要确保页面重新渲染或触发指令的 updated 钩子。

总结

通过 v-permission 自定义指令,可以在 Vue3 项目中轻松实现权限控制,移除无权限的元素,提升用户体验和项目安全性。根据实际需求,还可以进一步扩展此指令,例如实现隐藏元素而非移除元素、支持多种权限逻辑等。

📢 关于作者
嗨!我是头发秃头小宝贝,一名热爱技术分享的开发者,专注于Vue / 前端工程化 / 实战技巧等领域。
如果这篇文章对你有所帮助,别忘了 点赞 👍收藏 ⭐关注 👏,你的支持是我持续创作的最大动力!