async changePermissionCode() {
const codeList = await getPermCode();
this.setPermCodeList(codeList);
}
}
})
接下来它提供了三种按钮级别的权限控制方式,一一来看。
## 函数方式
使用示例如下:
本质上就是通过`v-if`,只不过是通过一个统一的权限判断方法`hasPermission`:
export function usePermission() { function hasPermission(value, def = true) { // 默认视为有权限 if (!value) { return def; }
const allCodeList = permissionStore.getPermCodeList;
if (!isArray(value)) {
return allCodeList.includes(value);
}
// intersection是lodash提供的一个方法,用于返回一个所有给定数组都存在的元素组成的数组
return (intersection(value, allCodeList)).length > 0;
return true;
}
}
很简单,从全局`store`中获取当前用户的权限码列表,然后判断其中是否存在当前按钮需要的权限码,如果有多个权限码,只要满足其中一个就可以。
## 组件方式
除了通过函数方式使用,也可以使用组件方式,`Vue vben admin`提供了一个`Authority`组件,使用示例如下:
使用`Authority`包裹需要权限控制的按钮即可,该按钮需要的权限码通过`value`属性传入,接下来看看`Authority`组件的实现。
同样还是使用`hasPermission`方法,如果当前用户存在按钮需要的权限码时就原封不动渲染`Authority`包裹的内容,否则就啥也不渲染。
## 指令方式
最后一种就是指令方式,使用示例如下:
拥有code ['1000']权限可见
实现如下:
import { usePermission } from '/@/hooks/web/usePermission';
function isAuth(el, binding) { const { hasPermission } = usePermission();
const value = binding.value; if (!value) return; if (!hasPermission(value)) { el.parentNode?.removeChild(el); } }
const mounted = (el, binding) => { isAuth(el, binding); };
const authDirective = { // 在绑定元素的父组件 // 及他自己的所有子节点都挂载完成后调用 mounted, };
// 注册全局指令 export function setupPermissionDirective(app) { app.directive('auth', authDirective); }
只定义了一个`mounted`钩子,也就是在绑定元素挂载后调用,依旧是使用`hasPermission`方法,判断当前用户是否存在通过指令插入的按钮需要的权限码,如果不存在,直接移除绑定的元素。
很明显,`Vue vben admin`的实现有两个问题,一是不能动态更改按钮的权限,二是动态更改当前用户的权限也不会生效。
解决第一个问题很简单,因为上述只有删除元素的逻辑,没有加回来的逻辑,那么增加一个`updated`钩子:
app.directive("auth", { mounted: (el, binding) => { const value = binding.value if (!value) return if (!hasPermission(value)) { // 挂载的时候没有权限把元素删除 removeEl(el) } }, updated(el, binding) { // 按钮权限码没有变化,不做处理 if (binding.value === binding.oldValue) return // 判断用户本次和上次权限状态是否一样,一样也不用做处理 let oldHasPermission = hasPermission(binding.oldValue) let newHasPermission = hasPermission(binding.value) if (oldHasPermission === newHasPermission) return // 如果变成有权限,那么把元素添加回来 if (newHasPermission) { addEl(el) } else { // 如果变成没有权限,则把元素删除 removeEl(el) } }, })
const hasPermission = (value) => { return [1, 2, 3].includes(value) }
const removeEl = (el) => { // 在绑定元素上存储父级元素 el._parentNode = el.parentNode // 在绑定元素上存储一个注释节点 el._placeholderNode = document.createComment("auth") // 使用注释节点来占位 el.parentNode?.replaceChild(el._placeholderNode, el) }
const addEl = (el) => { // 替换掉给自己占位的注释节点 el._parentNode?.replaceChild(el, el._placeholderNode) }
最后
四轮技术面+一轮hr面结束,学习到了不少,面试也是一个学习检测自己的过程,面试前大概复习了 一周的时间,把以前的代码看了一下,字节跳动比较注重算法,面试前刷了下leetcode和剑指offer, 也刷了些在牛客网上的面经。大概就说这些了,写代码去了~
祝大家都能收获大厂offer~
篇幅有限,仅展示部分内容