前端学习之组件级权限控制(vue 版)
一、组件级权限控制的内容
对于不同角色的用户,在同一个页面中,有不同的权限,比如:
功能显示状态的控制
- 普通用户只有搜索按钮,没有查看详情的按钮
- 管理员有编辑数据和删除数据的权限按钮
- 又或者管理员可以看到只有管理员才能看到的一个图表内容。
功能禁用状态的控制
- 普通用户能编辑表单中的部分数据,部分数据更新被禁用,而管理员能编辑所有数据。
组件级权限控制的实现方案
函数式权限控制
如通过 v-if="havePermission('sys:user:list')" 来控制组件的显示状态。
通过 :disabled="havePermission('sys:user:list')" 来控制组件的禁用状态。
指令式权限控制
这个属于面试常问的。
实际上核心就是 vue 的指令编写和 havePermission 函数
指令的编写:
局部指令
如果只是当前文件使用,可以直接定义在当前文件中,且需要在 setup 下面,且以 v 开头的驼峰式命名的变量
<script setup>
// 在模板中启用 v-highlight
const vHighlight = {
mounted: el => {
el.classList.add("is-highlight");
},
};
</script>
<template>
<p v-highlight>This sentence is important!</p>
</template>
全局指令
如果不在当前文件内编写的话,需要进行全局注册指令
import { createApp } from "vue";
import App from "./App.vue";
const app = createApp(App);
app.directive("highlight", vHighlight);
app.mount("#app");
vue 指令和使用指令的组件的生命周期钩子执行顺序
- 组件的 setup
- 组件的 beforeCreate
- 组件的 created
- 组件的 beforeMounted
- 指令的 created
- 指令的 mounted:此时使用 el.remove 可以移除组件,但是组件内部代码仍然执行,包括 beforUnmounted
- 组件的 mounted
组件式权限控制
组件式权限控制的话,实际上将函数式权限控制和插槽封装在一起。
进阶功能,组件通过插槽作用域将权限控制交还给调用者使用
组件式权限控制代码
<template>
<!-- 控制显隐,插槽作用域的数据提供给外部使用 -->
<slot v-if="showSlot" :userPermission="permissions"></slot>
</template>
<script setup lang="ts">
import { computed } from "vue";
const props = defineProps({
permission: { type: [String, Array] },
});
const permissions: any = []; // 用户具有的权限
const showSlot = computed(() => {
if (!props.permission) {
// 没有传入权限,直接显示
return true;
}
// 如果没有用户权限,直接不展示
if (!permissions) {
return false;
}
// 开始判断
if (Array.isArray(props.permission)) {
return props.permission.every((item: any) => permissions.includes(item));
} else {
return permissions.includes(props.permission);
}
});
</script>
<style scoped></style>
使用
<!-- 正常控制组件的显示状态 -->
<template>
<Authority :permission="['sys:user:list']">
<el-button>编辑</el-button>
</Authority>
</template>
<!-- 手动控制权限的具体效果,插槽组件提供 userPermission ,将控制权交还给调用者 -->
<template>
<div>
<Authority :permission="['sys:user:list']">
<template #default="{ userPermission }">
<el-button :disabled="!userPermission.includes('sys:user:list')">编辑</el-button>
</template>
</Authority>
</div>
</template>
什么情况下使用指令,什么情况下使用组件?
-
指令式权限控制 只影响组件元素的展示,不影响内部逻辑执行 还可以在外部通过 ref 引用,调用组件暴露的方法。
-
组件式权限控制的话,实际上将函数是权限控制和插槽封装在一起。
-
函数式权限控制,实际上就是通过 v-if,value 为执行一个判断是否有权限的函数。
什么时候使用指令?
- 按钮级别的 控制,或者一个元素级别的,无额外副作用的组件,比如组件内部不会自动请求数据,发送数据。
什么时候使用函数式权限控制或组件式权限控制?
- 都可以,看个人代码习惯。