权限指令
概述
权限指令基于 Vue 自定义指令机制实现,提供细粒度的前端权限控制能力。系统内置两种权限指令:
v-has-role- 角色权限指令,根据用户角色控制元素显示v-has-perm- 操作权限指令,根据权限标识控制按钮显示
技术实现
采用 Vue 原生的自定义指令(Custom Directives)机制,通过在元素挂载时检查用户权限,自动控制 DOM 元素的显示与隐藏。详细实现逻辑请参考 前端指南 - 权限控制系统。
配置角色权限
1. 创建角色代码
角色代码是角色权限的唯一标识符,用于在前端代码中进行权限判断。
操作步骤:
- 进入 权限管理 > 角色管理 界面
- 点击 新增 或选择已有角色点击 编辑
- 在 角色代码 字段中填入角色标识(要求:英文字符,系统内唯一)
- 填写其他必要信息后,点击 确定 保存

注意事项
- 角色代码必须使用英文字符(建议小写,如:
admin、manager) - 角色代码在系统中必须唯一,不可重复
- 角色代码一旦创建,建议不要随意修改,以免影响已有的权限配置
配置操作权限
1. 创建按钮权限标识
按钮权限标识用于细粒度的操作权限控制,通常对应具体的业务操作(如新增、编辑、删除等)。
操作步骤:
- 进入 权限管理 > 菜单管理 界面
- 点击 新增 或选择已有菜单点击 编辑
- 在 菜单类型 下拉框中选择 按钮
- 在 权限标识 字段中填入权限码(格式:
模块:功能:操作,如:sys:user:add) - 填写其他必要信息后,点击 确定 保存

权限标识命名规范
建议采用三段式命名格式:模块:功能:操作
- 模块:系统模块标识,如
sys(系统)、biz(业务) - 功能:具体功能模块,如
user(用户)、role(角色) - 操作:具体操作类型,如
add(新增)、edit(编辑)、delete(删除)、view(查看)
示例:sys:user:add、sys:role:edit、biz:order:delete
2. 为角色分配按钮权限
创建权限标识后,需要将其分配给相应的角色,用户才能拥有该操作权限。
操作步骤:
- 进入 权限管理 > 角色管理 界面
- 选择需要授权的角色,点击 设置权限
- 在弹出的对话框中,切换到 角色菜单 选项卡
- 在菜单树中找到刚才创建的按钮权限,勾选该选项
- 点击 确定 完成权限分配

前端使用指南
配置完成后,即可在前端页面中使用权限指令控制元素的显示与隐藏。
使用角色权限指令 v-has-role
角色权限指令用于根据用户角色控制功能模块或页面区域的显示。
基础用法:
vue
<template>
<!-- 单个角色判断 -->
<el-button v-has-role="'admin'" type="primary"> 管理员专属功能 </el-button>
<!-- 多个角色判断(满足任意一个角色即可显示) -->
<el-button v-has-role="['admin', 'manager']" type="primary">
管理功能
</el-button>
<!-- 控制整个功能区域 -->
<div v-has-role="['admin']">
<h3>管理员控制面板</h3>
<p>此区域仅管理员可见</p>
</div>
</template>应用场景:
- 控制管理后台的不同功能模块显示
- 根据用户角色展示不同的操作面板
- 隐藏普通用户不应看到的高级功能
使用操作权限指令 v-has-perm
操作权限指令用于细粒度的按钮级权限控制,精确控制用户的具体操作权限。
基础用法:
vue
<template>
<!-- 单个权限判断 -->
<el-button v-has-perm="'sys:user:add'" type="primary" @click="handleAdd">
新增用户
</el-button>
<!-- 多个权限判断(满足任意一个权限即可显示) -->
<el-button
v-has-perm="['sys:user:edit', 'sys:user:update']"
type="success"
@click="handleEdit"
>
编辑
</el-button>
<!-- 组合使用多个权限按钮 -->
<el-space>
<el-button v-has-perm="'sys:user:add'" type="primary" icon="Plus">
新增
</el-button>
<el-button v-has-perm="'sys:user:edit'" type="success" icon="Edit">
编辑
</el-button>
<el-button v-has-perm="'sys:user:delete'" type="danger" icon="Delete">
删除
</el-button>
</el-space>
<!-- 在下拉菜单中使用 -->
<el-dropdown>
<el-button type="primary">
更多操作 <el-icon class="el-icon--right"><arrow-down /></el-icon>
</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item v-has-perm="'sys:user:export'">
导出数据
</el-dropdown-item>
<el-dropdown-item v-has-perm="'sys:user:import'">
导入数据
</el-dropdown-item>
<el-dropdown-item v-has-perm="'sys:user:reset'" divided>
重置密码
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>应用场景:
- 控制列表页的增删改查按钮显示
- 限制敏感操作(如删除、导出)的执行权限
- 在表格行操作列中动态显示可用操作按钮
权限指令与路由守卫的区别
- 权限指令:控制页面内元素的显示与隐藏,属于前端视觉控制
- 路由守卫:控制页面访问权限,属于页面级别控制
重要提示: 前端权限控制仅用于提升用户体验,真正的权限验证必须在后端进行。前端权限可以被绕过,因此后端 API 必须实施完整的权限校验机制。
最佳实践
1. 权限粒度建议
vue
<!-- ✅ 推荐:细粒度权限控制 -->
<el-button v-has-perm="'sys:user:add'">新增</el-button>
<el-button v-has-perm="'sys:user:edit'">编辑</el-button>
<el-button v-has-perm="'sys:user:delete'">删除</el-button>
<!-- ❌ 不推荐:权限过于粗糙 -->
<el-button v-has-perm="'sys:user'">所有操作</el-button>2. 权限指令组合使用
vue
<template>
<!-- 同时满足角色和操作权限 -->
<div v-has-role="'admin'">
<el-button v-has-perm="'sys:config:edit'" type="primary">
系统配置
</el-button>
</div>
</template>3. 权限缺失时的提示
vue
<template>
<el-tooltip content="您没有删除权限" :disabled="hasDeletePerm">
<span>
<el-button
v-has-perm="'sys:user:delete'"
type="danger"
:disabled="!hasDeletePerm"
>
删除
</el-button>
</span>
</el-tooltip>
</template>常见问题
Q1: 权限指令不生效,元素仍然显示?
可能原因:
- 用户权限未正确加载(检查 Pinia store 中的权限数据)
- 权限标识拼写错误(区分大小写)
- 用户未重新登录获取最新权限
解决方案:
javascript
// 在浏览器控制台检查用户权限
import { useUserStore } from "@/pinia/modules/user";
const userStore = useUserStore();
console.log("角色列表:", userStore.userInfo.roleCodes);
console.log("权限列表:", userStore.userInfo.authCodes);Q2: 如何在 JavaScript 代码中判断权限?
解决方案:
javascript
import { useUserStore } from "@/pinia/modules/user";
const userStore = useUserStore();
// 判断是否拥有某个角色
const hasAdminRole = userStore.userInfo.roleCodes.includes("admin");
// 判断是否拥有某个权限
const hasAddPerm = userStore.userInfo.authCodes.includes("sys:user:add");
// 在方法中使用
const handleOperation = () => {
if (!hasAddPerm) {
ElMessage.warning("您没有新增权限");
return;
}
// 执行操作...
};Q3: 权限配置后需要多久生效?
权限配置修改后:
- 后端权限:立即生效(下次 API 请求时验证)
- 前端权限:需要用户重新登录或刷新页面以重新加载权限信息

