这篇文章将为大家详细讲解有关如何使用Vue实现按钮级权限方案,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
演示
在年初开发一个中后台管理系统,功能涉及到了各个部门(产品,客服,市场等等),在开始的版本中,我和后端配合使用了花裤衩手摸手系列的权限方案,前期非常不错,但是慢慢的随着功能增多,业务越来越复杂,就变得有些吃力了,因为我们的权限动态性太大了
- <李>
手摸手系列权限方案是有比较清晰的权限划分的,而我们公司部门的岗位职责有时比较模糊。
李> <李>后端采用RBAC权限方案,为了达到第1点要求,将角色划分的很细,并且角色有时频繁变动,导致每一次前端都需要手动维护
李> <李>为了解决上面2个痛点,我将原方案进行了一丢丢改造。
李> <李>前端不再以角色来控制权限,而是以更小粒度的操作(接口)来控制,也就是前端不关心角色
李> <李>路由还是由前端维护(我们的后端很排斥维护和他们不相干的东西:乔伊:),但改为通过操作列表对权限路由进行过滤
李> <李>使用单一的方式(方便维护)控制页面的局部权限,不再使用自定义指令方式,而是通过函数式组件,原因是使用自定义指令有多余的开销(插入再移除)
李><强>后端的配合:强>
<代码> routerName
代码>
<强>有一些注意点:强>
- <李>
比如一个有权限的列表页面,同时这个列表接口被权限页B面使用,现在你配置权限让某一个用户没有一个页面权限,但可以使用B页面,如果你的本意是可以使用B页面的所有功能,这时就会有问题,所以尽量不要将权限接口跨页面使用,需要分清哪些数据需要通过字典接口获取还是通过权限接口获取
李> <李>有些人可能会纠结,前端维护权限安全吗?肯定是不安全的,安全性主要还在后端这边把控,后端做好数据和接口方面的权限控制,前端做权限控制我认为主要还是为了交互体验等。没有权限你为什么要让我看到那一坨?
李> <李>在使用这种方式之前,要明确当前场景是否确实需要这么做,毕竟在项目比较大且接口很多的情况下,你跟操作码之间有一场持久战
<强>实现
强>
<强>操作列表示例
强>
以宁静的风格接口为例
const operations =, ( ,{ ,url: & # 39;/xxx # 39; 类型:大敌;& # 39;得到# 39; ,名字:& # 39;查询xxx # 39;, ,routeName: & # 39; route1& # 39;,,//,接口对应的路由 操作码:大敌;& # 39;XXX_GET& # 39;,//,操作码,不变的 }, ,{ ,url: & # 39;/xxx # 39; 类型:大敌;& # 39;文章# 39; ,名字:& # 39;新增xxx # 39;, ,routeName: & # 39; route1& # 39; 操作码:大敌;& # 39;XXX_POST& # 39; },//,…… )
<强>路由的变化强>
在路由的,元中增加一个配置字段如,requireOps,值可能为,字符串或者,数组,这表示当前路由页面要显示的必要的操作码,,数组类型是为了处理一个路由页面需要满足同时存在多个操作权限时才显示的情况。若值不为这2种则视为无权限控制,任何用户都能访问
由于最终需要根据过滤后的权限路由动态生成菜单,所以还需要在路由选项中增加几个字段处理显示问题,其中,隐藏优先级大于,可见
隐藏起来 可见 const permissionRoutes =, ( ,{ ,//可见:假的, ,//隐藏:没错, ,路径:& # 39;/xxx # 39; ,名字:& # 39;route1& # 39; ,元:{ 标题:才能,& # 39;路由1 & # 39;, requireOps才能:& # 39;XXX_GET& # 39; }, ,//? ,} )
由于路由在前端维护,所以以上配置只能写死,如果后端能同意维护这一份路由表,那就可以有很多的发挥空间了,体验也能做的更好。
<强>权限路由过滤
强>
先将权限路由规范一下,同时保留一个副本,可能在可视化时需要用到
const routeMap =,(路线,,cb),=祝辞,routes.map (route =祝辞,{ ,if (route.children ,,, route.children.length 祝辞,0),{=,,route.children  routeMap (route.children, cb) ,} ,return cb(路线) }) const hasRequireOps =, ops =祝辞,Array.isArray (ops), | |, typeof ops ===, & # 39;字符串# 39; const normalizeRequireOps =, ops =祝辞,hasRequireOps(运维) ,? [].concat(…[行动]) ,:null const normalizeRouteMeta =, route =祝辞,{ ,const meta =, route.meta =, { ,……(route.meta | |, {}) ,}=,,meta.requireOps  normalizeRequireOps (meta.requireOps) return 路线 } 时间=permissionRoutes routeMap (permissionRoutes, normalizeRouteMeta) const permissionRoutesCopy =, JSON.parse (JSON.stringify (permissionRoutes))如何使用Vue实现按钮级权限方案