用户权限控制的实现
在Web开发中,用户权限一般分为两种:页面权限 和 按钮权限。
页面权限也就是页面菜单,通过后端和vue-router就很容易实现,这里就不赘述了。
按钮权限,也可以说是页面元素权限,比如一个按钮、一个表单、一个查询结果等,这些元素是否要显示,都可以通过权限控制。
本文将介绍如何通过 自定义指令 和 组件封装 两种方式来实现 按钮权限控制。
自定义指令
自定义指令是一种轻量级的方式,可以直接控制 DOM 元素的显示或隐藏。
1. 指令代码
ts
import { Directive } from 'vue';
interface PermissionOptions {
value: string | string[];
}
const hasPermission = (permissions: string[], required: string | string[]) => {
if (Array.isArray(required)) {
return required.some((perm) => permissions.includes(perm));
}
return permissions.includes(required);
};
const permission: Directive = {
mounted(el, binding) {
const userPermissions = ['view', 'edit', 'delete']; // 模拟用户拥有的权限数据
const { value }: PermissionOptions = binding;
if (!hasPermission(userPermissions, value)) {
// 移除dom
el.parentNode && el.parentNode.removeChild(el);
}
},
};
export default permission;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2. 注册指令
在项目的入口文件中进行全局注册:
ts
import { App } from 'vue';
import permission from './directives/permission';
export function registerDirectives(app: App) {
app.directive('permission', permission);
}
1
2
3
4
5
6
2
3
4
5
6
3. 使用指令
在组件中使用:
vue
<template>
<div>
<button v-permission="'edit'">编辑</button>
<button v-permission="['view', 'delete']">查看或删除</button>
</div>
</template>
1
2
3
4
5
6
2
3
4
5
6
跳转到 Vue演练场 查看效果。
4. 优点和缺点
优点
- 轻量化:无需额外的组件封装,直接操作 DOM,性能较好。
- 灵活:可以轻松结合任何组件或 HTML 元素使用。
缺点
- 难以复用复杂逻辑:如需要进行复杂的渲染逻辑,自定义指令可能显得局限。
- 难以测试:DOM 操作逻辑难以进行单元测试。
- 内存泄漏:只是移出了组件的DOM,并没有真正销毁组件,可能会导致一些问题。
可以查看 远方 大佬的视频讲解:抖音: 自定义指令控制权限的弊端
组件封装
通过封装组件,可以在模板中以声明式的方式实现权限控制,同时支持插槽功能。
1. 实现代码
vue
<template>
<slot v-if="isAllowed"></slot>
</template>
<script setup lang="ts" name="PermissionCom">
import { defineComponent, computed, PropType } from 'vue';
const props = defineProps<{
permission: string | string[]
}>()
// 这个值可以从store中取
const userPermissions = ['edit', 'view', 'delete']
const isAllowed = computed(() => {
const { permission } = props;
if (Array.isArray(permission)) {
return permission.some((perm) => userPermissions.includes(perm));
}
return userPermissions.includes(permission);
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2. 使用组件
vue
<template>
<div>
<Permission permission="edit">
<button>编辑</button>
</Permission>
<Permission :permission="['view', 'delete']">
<button>查看或删除</button>
</Permission>
</div>
</template>
<script setup lang="ts" name="PermissionExample">
import Permission from '@/components/Permission.vue';
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
跳转到 Vue演练场 查看效果。
3. 优点和缺点
优点
- 可复用性强:通过组件封装,可以更容易地在项目中统一管理权限逻辑。
- 测试友好:组件逻辑易于单元测试,适合复杂的业务场景。
- 支持插槽:可以对渲染内容进行灵活的控制。
缺点
- 性能开销略高:每次渲染都会创建组件实例。
- 模板冗长:相比指令方式,模板代码显得稍长。