基于Vue实现后台系统权限控制的示例代码

2020-06-13 10:27:04易采站长站整理


<el-menu router>
<el-menu-item v-for="(route, index) in $router.options.routes[2].children"
:route="route"
:index="route.name">
<i class="ion" v-html="route.icon"></i>{{route.name}}
</el-menu-item>
</el-menu>

当然这样只能循环出一级菜单,如果还有二级路由需要对应二级菜单的话,就得判断并循环children节点,比较简单就不放更多代码了,菜单权限控制到这里就完成了。

Vue按钮权限控制

按钮权限控制与菜单权限控制的实现思路类似,也是根据用户权限判断各个按钮的显示与否,方式无非是v-if或自定义指令,而且只要将v-if背后的权限校验逻辑抽象成方法,无论是代码量还是使用形式上都跟自定义指令几乎一样,但v-if的特点是它会响应数据变化,因此随着应用的运行会频繁触发权限校验,而权限在应用的整个生命周期内其实只需校验一次,为了避免无谓的程序执行,这里可以用自定义指令来实现,伪码:


Vue.directive('has', {
bind: function (el, binding) {
if(!has(binding.value)){
el.parentNode.removeChild(el);
}
}
});

//用法:
<btn v-has='get,/sources'>按钮</btn>

注意在指令bind回调里有一个has()方法,这就是权限校验方法,我们同时将这个方法全局混合到Vue对象中,使应用里的每个组件都可以访问到这个方法,便于为界面上的v-if提供支持,例如:


<div v-if="has('get,/sources') && something">
一个需要同时具备'get,/sources'权限和somthing为真值才显示的div
</div>

这样一来凡是需要依据权限实现的按钮显隐控制和界面变化都可以很方便的实现。

但按钮权限控制真正麻烦的地方不在于如何实现,而在于高昂的维护成本。我们假设按钮Btn绑定了点击回调Fn,回调Fn里发起了请求Req,请求Req需要某个资源的访问权限,最终你要根据用户是否拥有Req的权限,决定Btn是否显示,而Req跟Btn之间并没有直接关联,所以我们就要人肉维护他们的关系,一个复杂项目里的按钮有个几十上百都很正常,随着业务的变更去维护这么多按钮的权限,想想都头疼。

有一个方法可以绕开这个烂摊子,那就是前端放弃对视图层的控制,退到请求层面,在请求发起前集中拦截,这时可以直接根据请求方法和请求地址来校验权限,除了实现一个拦截器之外不需要额外的代码,可以说非常优雅了。以axios为例,拦截器大概长这样:


axios.interceptors.request.use(function (config) {
if(!has(config)){