前端 RBAC基于角色的权限控制(按钮级别)

实现前端按钮级别 RBAC 权限控制的核心要点

1.权限状态管理(全局存储)

将后端返回的权限码存入 Pinia/Vuex,提供统一的权限判断方法;

js 复制代码
//stores/permission.ts
import { defineStore } from 'pinia'

export const usePermissionStore = defineStore('permission', {
  state: () => ({
    // 存储当前用户的所有权限码
    permissionCodes: [] as string[]
  }),
  actions: {
    // 初始化权限码(登录后调用)
    setPermissionCodes(codes: string[]) {
      this.permissionCodes = codes
    },
    // 核心方法:判断是否拥有某个权限
    hasPermission(code: string) : boolean {
      // 超级管理员默认拥有所有权限(可选)
      if (this.permissionCodes.includes('admin')) return true
      return this.permissionCodes.includes(code)
    }
  }
})

2.封装权限指令

通过自定义v-permission指令快速实现按钮的显示 / 隐藏 / 禁用,降低业务代码耦合;

js 复制代码
//directives/permission.ts
import { usePermissionStore } from "@/stores/permission";

// 注册自定义指令:v-permission,用于控制元素的显示与隐藏
// 默认导出一个函数,接收Vue应用实例作为参数
export default function setupPermissionDirective(app: any) {
    app.directive('permission', {       // 指令名称为permission。vue会自动加上"v-"前缀,在vue中使用时为v-permission
        mounted(el: HTMLElement, binding: any) {  // 指令挂载时的钩子函数,el为绑定指令的元素,binding为指令的绑定信息
            const { value: permissionCode } = binding;
            const permissionStore = usePermissionStore();

            // 如果没有传入权限码,默认不显示该元素
            if(!permissionCode) {
                el.style.display = 'none';
                return;
            }
            // 检查权限,没有权限则移除元素
            if (permissionCode && !permissionStore.hasPermission(permissionCode)) {
                el.parentNode && el.parentNode.removeChild(el);
            }
        }
    });
}

在main.ts中注册全局指令

js 复制代码
//main.ts
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
// 引入权限指令
import setupPermissionDirective from './directives/permission'

const app = createApp(App)

app.use(createPinia())
// 注册权限指令
setupPermissionDirective(app)

app.mount('#app')

3.业务中使用

(前后端配合):前端控制展示,后端校验接口权限,避免权限绕过。

js 复制代码
<script setup lang="ts">
import {ElButton} from 'element-plus';
import { usePermissionStore } from './stores/permission';
const permissionStore = usePermissionStore();
// 模拟登录,设置用户权限
permissionStore.setPermissionCodes(['btn:user:add', 'btn:user:edit']);
// permissionStore.setPermissionCodes(['btn:user:add', 'btn:user:edit', 'btn:user:delete']);
</script>

<template>
  <div class="user-actions">
    <!-- 有"btn:user:add"权限才显示新增按钮 -->
    <el-button v-permission="'btn:user:add'" type="primary">新增用户</el-button>
    
    <!-- 有"btn:user:edit"权限才显示编辑按钮 -->
    <el-button v-permission="'btn:user:edit'">编辑用户</el-button>

     <!-- 有"btn:user:delete"权限才显示删除按钮 -->
    <el-button v-permission="'btn:user:delete'">删除用户</el-button>
  </div>
</template>

<style scoped></style>

大白话:用户登录后,后端返回该用户的所有权限,如编辑,添加,删除等,前端存储用户权限列表到pinia中,并提供提供统一的权限判断方法hasPermission。

前端封装自定义指令,v-permission实现按钮的显示/隐藏,判断如果元素绑定的指令在用户权限列表里,则显示,否则隐藏。

前端在元素上使用v-permission绑定自定义指令,控制按钮的显示与隐藏。

相关推荐
梦曦i6 小时前
@meng-xi/create-uni-app vs unibest:轻量脚手架与重型框架的定位之争
前端·uni-app
平头哥技术团队7 小时前
Day 10 | 工欲善其事:VS Code 配置与项目归档
android·开发语言·前端·javascript·html·交互
乌恩大侠7 小时前
GH200 新增 NVMe SSD 分区、格式化与挂载完整流程
运维·服务器·前端
yume_sibai7 小时前
Element Plus 数据展示组件完全指南(15个核心组件)
前端·javascript·vue.js
qiuhaipeng18 小时前
Claude code 升级后上下文长度变短问题
java·前端·数据库
zzz_23688 小时前
个人 AI 记忆如何跨工具复用:用 Markdown、索引和 Skill 搭一个可治理的记忆库
前端·人工智能·react.js·前端框架·agent·agent测评
剑之所向9 小时前
.NET 官方`System.Threading.Channels`
前端·javascript·数据库
计算机魔术师10 小时前
GPT-6 Astra幻觉砍到2%,却被一种老招数轻松绕过
前端
cjy00011110 小时前
2026AI 产品如何从一次性 Demo 变成可重复使用的业务工具?
前端·人工智能·fde
IT_陈寒11 小时前
React的状态更新坑得我差点加班到天亮
前端·人工智能·后端