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

相关推荐
学习java的小库里2 小时前
EasyExcel复杂导出
java·前端
muddjsv2 小时前
前端开发通用全流程:从需求到上线,步步拆解
前端
Mr Xu_2 小时前
从零实战!使用 Mars3D 快速构建水利监测 WebGIS 系统
前端·3d·webgis
wuhen_n2 小时前
类型断言:as vs <> vs ! 的使用边界与陷阱
前端·javascript·typescript
⑩-2 小时前
VUE3-组件通信
前端·javascript·vue.js
哆啦A梦15882 小时前
Vue3魔法手册 作者 张天禹 02
前端·vue.js·typescript
老前端的功夫2 小时前
抛弃 `!important`,让 CSS 优先级变大
前端·javascript·css·npm·node.js
熊文豪2 小时前
Tomcat+cpolar 让 Java Web 应用随时随地可访问
java·前端·tomcat·cpolar
衫水2 小时前
如何在离线情况下部署项目(前端VUE + 后端Python)
前端·vue.js·python