大家好,我是G探险者。
关于角色与权限控制,通常是分为两大类:一种是菜单权限;一种是操作权限。
菜单权限是指,每个角色对应着可以看到哪些菜单,至于每个菜单里面的每个按钮,比如增删改查等等这类按钮控制不到这个粒度。简单来说就是控制看到的菜单多少。
操作权限是指,每个角色对于所看到的数据具有哪些操作权限,就是增删改查这些具体的操作,简单来说就是读写权限。
一套完整的角色访问控制:是应该包含这两种控制的。通常二者也是交叉在一起进行访问控制的。
Vue.js 提供了灵活的方式来实现角色权限控制,本文将深入探讨如何通过 Vue 实现角色权限控制,特别是基于按钮级别的权限控制。
1. 角色权限控制的概述
角色权限控制可以分为两个层面:
- 菜单权限:决定用户能看到哪些菜单和页面。
- 操作权限:控制用户对数据的操作权限,例如增、删、改、查等。
在 Vue 中实现角色权限控制,通常是在前端页面中动态渲染菜单和按钮,并通过与后端权限数据的对比,来决定用户是否有权限显示和操作这些元素。本文重点讨论如何实现按钮级别的权限控制,即根据用户的角色来控制他们能执行哪些操作。
2. 基本思路
角色权限控制的核心思想是:
- 用户权限通过后端接口返回,前端根据这些权限数据来决定页面中哪些按钮显示,哪些禁用,哪些完全移除。
- Vue 的动态渲染机制允许我们根据不同用户的权限来动态控制按钮的展示和行为,确保用户只能看到和操作他们有权限访问的功能。
3. Vue 实现角色权限控制
3.1 权限控制插件:v-perm-code
为了简化权限控制的实现,我们可以创建一个自定义 Vue 指令 (v-perm-code
),该指令根据当前用户的权限动态控制按钮的显示、禁用或移除。
3.1.1 指令的基本实现
首先,我们通过 Vue 的 Vue.directive
注册一个名为 perm-code
的自定义指令,该指令在绑定时检查每个按钮的权限,并根据用户的权限动态调整按钮的状态。
import { isObjectLike } from "lodash-es";
import { btnPermRemove, btnPermControl } from "globalSettings";
export default {
install(Vue) {
Vue.directive("perm-code", {
async bind(el, binding, vnode) {
// 开发模式下是否关闭按钮级别权限控制
if (!btnPermControl) return;
let { value: permCode } = binding; // 获取按钮的权限码
if (!permCode) return false; // 如果没有权限码则退出
const dom = el;
const _store = vnode.context.$store;
let pathnameCurrent = vnode.context.$route.path;
if (!pathnameCurrent) pathnameCurrent = location.pathname;
const pathnameStore = _store.state.router.pathname;
// 动态获取权限码
if (isObjectLike(permCode)) {
permCode = Vue.filter(permCode.filter)(permCode.value);
}
// 是否显示无权限的按钮但禁用
const permShow = el.getAttribute("perm-show") === "true";
// 从store获取权限码列表
if (pathnameCurrent && pathnameStore !== pathnameCurrent) {
await _store.dispatch("router/getCurrentPermList", pathnameCurrent);
}
const permCodeList = _store.getters["router/permCodeList"];
// 根据权限控制按钮的显示和状态
dom.setAttribute("perm-code", permCode);
if (permCodeList.includes(permCode)) {
dom.style.display = "inline-block";
dom.title = `有权限按钮: ${permCode}`;
} else if (permShow) {
dom.style.display = "inline-block";
dom.setAttribute("disabled", "disabled");
} else {
dom.title = `无权限按钮: ${permCode}`;
if (btnPermRemove) {
setTimeout(() => {
dom.parentNode.removeChild(el); // 移除无权限按钮
}, 0);
} else {
dom.style.display = "inline-block";
}
}
},
});
},
};
3.1.2 指令的核心逻辑
- 权限码 (
permCode
):每个按钮的权限码,通常由后端返回并与前端匹配,用于判断用户是否有权限执行某个操作。 - 权限列表 (
permCodeList
):从 Vuex 中获取当前用户的权限列表,这些权限码来自后端接口。 - 按钮显示/禁用/移除:
- 如果用户有权限(即权限码存在于
permCodeList
中),按钮显示并且可以点击。 - 如果没有权限,但
perm-show="true"
,则按钮仍然显示,但禁用。 - 如果没有权限且
perm-show
不为true
,按钮会被从 DOM 中移除(如果btnPermRemove
为true
)。
- 如果用户有权限(即权限码存在于
3.2 按钮与权限结合:btnPermCode
在页面组件中,每个按钮都包含一个 btnPermCode
属性,该属性指定了与之关联的权限码。例如:
data() {
return {
buttonList: [
{
label: "新增",
type: "add",
click: this.openAdd,
btnPermCode: "add", // 权限码
},
{
label: "删除",
type: "delete",
click: this.clickDelete,
btnPermCode: "delete", // 权限码
},
{
label: "发布",
type: "publish",
click: this.clickPublish,
btnPermCode: "publish", // 权限码
},
// 更多按钮...
],
};
},
3.3 Vuex 与权限列表管理
用户的权限列表存储在 Vuex 中,通过后端接口动态获取。当用户访问一个页面时,Vuex 会存储与该页面相关的权限码,指令 v-perm-code
会通过 Vuex 获取这些权限,并根据权限决定按钮的展示。
const permCodeList = _store.getters["router/permCodeList"];
通过这种方式,前端可以确保根据当前用户的角色,动态显示和操作相关功能。
3.4 实际应用
在实际应用中,通常会有以下几种按钮操作:
- 增删改查:用户可以根据权限执行不同的数据操作,如新增、删除、编辑、查看等。
- 批量操作:例如批量删除、批量发布,前端根据权限判断是否显示这些操作按钮。
- 导入导出:当用户拥有导入导出的权限时,显示相应的按钮,否则不显示。
4. 总结
通过 Vue 的自定义指令和 Vuex 的权限管理,我们可以在前端实现细粒度的角色权限控制。v-perm-code
指令结合 btnPermCode
和权限码列表,实现了基于权限的按钮显示、禁用、移除等功能。后端返回的权限数据与前端进行匹配,确保用户只能访问和操作他们有权限的功能。这种方式使得前端权限控制更加灵活和可维护,适用于大多数基于角色的权限管理系统。
通过这种方式,我们可以在 Vue 中高效地实现角色权限管理,确保不同角色的用户只看到和操作他们有权限的页面和功能,提高了系统的安全性和用户体验。