权限控制程度分为:1. 页面级 2. 组件级 3. 代码级
1. 页面级
这是大部分前端遇到的级别。依靠路由守卫,如果没有权限,就看不到菜单,就进不到页面。不会给页面带来侵入性。什么是侵入性,就是写页面组件的时候,还要考虑权限。
2. 组件级
有没有权限都可以看到页面组件,但是不同权限的人,看到的东西不同。比如按钮,没有权限的操作不了,或者看不到这个按钮。这就会产生一些侵入性,写页面组件的时候,需要考虑到权限。
我们现在要做的就是尽量减少组件级权限控制带来的侵入性。如果权限只是控制可见度的话,我们还可以做优化,如果是不同权限,点击按钮调用不同函数的话,那就不好优化了。现在针对第一种情况来优化。
我们可以用一个权限组件将需要权限控制的组件包裹住。给属性 permissions 传入参数 ,如果权限包含 'sys:user:add' 就显示按钮。
<Authority permissions="sys:user:add"> <button>新增用户</button> </Authority> <Authority :permissions="['sys:user:view', 'sys:user:update']"> <button>新增用户</button> </Authority>
如果权限控制的不是显示隐藏,而是控制的能否点击呢,我们这个组件可以交还一些控制权,让开发人员根据情况去控制。通过作用域插槽,返回用户的所有权限 userPermissions。
<Authority> <template #default="{ userPermissions }"> <button :disabled="!userPermissions.includes('sys:user:add')">新增用户</button> </template> </Authority>
我们这个组件提供了两个功能:一个预设的可见不可见,一个让开发者自行处理。代码如下:
<template> <slot v-if="showSlot" :userPermissions="permissions"></slot> </template> <script setup> import { computed } from "vue"; import { useAuth } from "./useAuth.js"; const props = defineProps({ permission: { type: [String, Array], }, }); const { permissions } = useAuth(); const showSlot = computed(() => { if (!props.permission) { // 没传入权限,直接显示 return true; } if (!permissions) { // 没有任何权限,直接隐藏 return false; } if (Array.isArray(props.permission)) { return props.permission.every((p) => permissions.includes(p)); } else { return permissions.includes(props.permission); } }); </script>
3. 代码级(函数级)
哪些权限的人可以调用这个函数,哪些不可以。或者调这个函数产生不同的结果。但是这种情况很少。