Vue|前端权限设计实现——按钮级

一直对权限设计很感兴趣,以前写后端代码时,搞过权限设计,挺有意思的,但是前端按钮级别的权限设计了解过,却还没具体实现过,最近项目打算对权限进行细分,先研究下前端的权限吧。
权限设计的出发点在于,让不同权限的用户,看到的内容、可实现的操作是不同的。
【Vue|前端权限设计实现——按钮级】到具体设计上来说,可以分为路由级权限和按钮级权限,从实现的难以层度上来说,都挺简单的,这篇博客主要讲按钮级别的权限控制。
按钮级权限需要做的是什么?
做权限控制,首先要知道要实现的目的是什么。
按钮级权限控制比较简单,根据身份不同,可以看到的按钮、可操作的功能也不相同。
首先要进行身份的区分和校验,可根据服务端下发的用户权限类别,提取出公共方法。
// ../utils/auth.js 文件位置//获取当前客户权限 export function getCurrentAuthority(){ ... return ["admin"] }//校验权限 export function check(authority = []){ let current = getCurrentAuthority(); return current.some(item=>item.includes(item)) }//登录校验 export function isLogin(){ const current = getCurrentAuthority(); return current && current[0] !== "guest"; }

两种实现方法
抽离出公共方法进行身份提取和校验后,在不同的组件中就可以使用了,最粗暴的方法,就是直接使用 v-if 来进行疯狂的判断。
但是这种方法不优雅,而且会对原有就使用 v-if 的内容造成困扰,因此可以将权限判断进行使用上的封装,主要有两种方法,一是组件,二是指令。
1. 组件方式
既然 v-if 不太优雅,那么是否可以将 v-if 的功能封装呢,答案当然是可行的,我们只需要在需要权限控制的内容外部再嵌套上一层组件,通过外层组件来判断内层组件是否渲染,就可以实现我们所需要的 v-if 的能力。
关于这个权限组件,我们可以进行思考下。
首先,权限组件并不需要有具体的 dom 渲染,它的作用只是根据条件来判断是否来渲染它嵌套的具体业务组件。这样的话,它可以不具备 template 模板内容,只需要具体逻辑即可,这样它可以只是纯粹的函数式组件,通过引用封装好的权限校验方法,来判断props中所允许的权限。
组件实现:

思路:
通过 props 传递允许的权限,在 render 函数中,通过上下文取出 props 和 slot 插槽内容,通过 check 方法校验 props 传递的权限是否通过,根据结果渲染 slot 的内容,实现权限控制。
组件使用:

注:Authorized 组件会在多个地方使用,可以进行全局注册,具体代码不展示
2.指令方式
使用组件方式进行权限控制,基本已经可以很好的满足我们实现按钮级权限控制的需求了,只需要在需要控制权限的按钮外面添加组件。
不过每次都需要在外面嵌套组件,还是比较繁琐的,我们可以参考下 v-if 进行自定义指令控制。
//./directives/auth.js import { check } from '../utils/auth.js'; function install(Vue, options = {}) { Vue.directive(options.name || 'auth', { inserted(el, binding) { if (!check(binding.value)) { el.parentNode && el.parentNode.removeChild(el); } } }) }export default { install }

思路:
接收自定义指令 binding 中传递的参数,通过 check 函数进行校验,校验未通过时,获取当前指令所在节点的父节点,来删除掉当前节点,实现权限控制。
指令注册:
// main.js import auth from './directives/auth.js'Vue.use(auth)

指令使用:

优缺点
使用组件方式来实现权限控制,在权限修改后会比较灵活的渲染受控部分,同时使用时候会稍微繁琐;
指令方式实现的权限控制,使用起来会比较简洁,但是是通过删减 dom 节点的方式实现的,因此只有在第一次时控制。
权限在赋予后,不会随意变动,可以根据使用场景来选用两种不同的方式。
相关资料
1. Vue 函数式组件
2. 自定义指令

    推荐阅读