前端 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绑定自定义指令,控制按钮的显示与隐藏。

相关推荐
风骏时光牛马1 小时前
数据可视化管理平台
前端
仿生狮子6 小时前
OpenAI 攻下千禧年难题之后,开发者似乎无动于衷
前端·数学·vibecoding
Lvan的前端笔记9 小时前
docker:每个前端项目一个 Nginx 容器还是只有一个Nginx容器
前端·nginx·docker
三天不学习9 小时前
Egg.js 4 突然爆火,原因是否归结于AI 原生落地需求爆发?
前端·javascript·全栈·egg.js
xcs1940510 小时前
前端 vue 的前端页面debugger 进不去
前端·javascript·vue.js
明月_清风11 小时前
Deno 终局来了:从挑战 Node 到被 Cloudflare 收编
前端·后端·node.js
Csvn12 小时前
框架性能优化
前端
回眸&啤酒鸭14 小时前
【回眸】OpenSwarm 多智能体协作系统实战指南
大数据·前端·人工智能
用户693717500138414 小时前
2026,程序员的时代拐点到了
android·前端·后端