vue结合AntDesign实现后台系统的权限分配(⽀持⽆限⼦级嵌套)
最近公司的业务需要,要做⼀个后台管理系统的管理系统类似于这样⼦
功能需求如下:
左边是权限菜单,右边对应的是具体权限.
1.⽗级权限菜单选中,⽗级权限菜单的权限包括其中所有⼦级权限菜单的权限也要选中,⽗级权限菜单取消选中,同理. 如下图所⽰
2.⽗级权限中所有的权限没有全部选中,⽗级权限菜单属于半选中状态(注意这⾥⽗级权限菜单和⼦级权限菜单是相对的,⽗级权限菜单可以是⼦级权限菜单,⼦级权限菜单也可以是⽗级权限菜单),如下图所⽰
3.最后记录当前所选权限的数量,发送给后台.
是不是感觉很简单,那就撸起袖⼦开⼲.
⾸先就要有⼀个思路,这个项⽬最多只有两级权限菜单,于是我就想我直接写死不就⾏了嘛?,当然就顺利的完成了.但是产品经理告诉我后期要扩展,可能有很多嵌套的层级.嗯....好吧.这样⼦⼀来,嵌套⼀个⼦级权限菜单,我岂不是就要修改⼀次代码,这对于我来说是不允许出现的,怎么能写出这种垃圾代码了,于是乎点了⼀⽀烟,思考了⼀下,我还
是放弃吧!
开玩笑的,没办法啊,想要⼯资就只有⼲啊,产品需求也是合情合理的,我还有什么话说.
接下来就直接给出源码,源码后⾯有思路的具体解释.
源码:
<template>
<div class="addRole">
<ACard
title="新增⾓⾊权限"
>
<template slot="extra">
<AButton type="primary" @click="goBack">返回</AButton>
</template>
<ARow >
<ACol :span="6" >
<div class="role-table" >
<div class="role-list">权限明细</div>
<div class="role-tree">
<ATree
checkable
:autoExpandParent="autoExpandParent"
:expandedKeys="expandedKeys"
class="scroll"
@expand="onExpand"
v-model="checkedKeys"
checkStrictly
@check="checkBoxCheck"
:treeData="permissionTreeData"
>
<template slot="title" slot-scope="record">
<span  @click="select(record.key)">{{record.name}}</span>
</template>
</ATree>
</div>
</div>
</ACol>
<ACol :span="1" >
<div >
<img :src="publicPath+$app.arrowPath" />
</div>
</ACol>
<ACol :span="17" >
<div >
<div class="role-list">操作权限 (完成编辑后请点击保存按钮保存设置)</div>
<div class="role-tree">
<!--<ACheckboxGroup    v-model="permissionIds">-->
<ACheckbox :checked="item.checked" @change="permissChange(item,$event)" :value="item.id" v-for="item in permissionChecks" :key="item.name">{{item.name}}</ACheckbox>                            <!--</ACheckboxGroup>-->
</div>
</div>
</ACol>
</ARow>
<div class="submit">
<p>当前已选择<span >{{permissionIds.length}}</span>项权限</p>
<div>
<AButton @click="resetPermissItemState">取消</AButton>
<AButton type="primary" @click="sendData">保存</AButton>
</div>
</div>
</ACard>
</div>
</template>
<script>
import {getPermissiontypes,getPermissionList,addRoles} from '@/api/AddRole'
import {getJurisdictions} from '@/api/Role'
export default {
name: 'AddRole',
data(){
return{
publicPath: v.BASE_URL,
form:this.$ateForm(this),
rules:{},
/
/显⽰的树权限
permissionTreeData:[],
expandedKeys:[],
autoExpandParent:true,
//选中权限分类的id
selectKey:'',
selectedKeys: [],
//选中权限的id的集合
permissionIds:[],
//权限复选框集合
permissionChecks:[],
/
/权限集合
permissionArr:[],
//全选和半选样式
checkedKeys:{
checked:[],
halfChecked:[]
},
//保存所有的权限类⽬id
permissTypeIds:[],
checkedLength:0
}
},
mounted(){
this.setRules();
//获取全部权限
getJurisdictions()
.then(res=>{
if(res&&res.data){
//设置树形控件需要显⽰的数据格式
this.permissionTreeData = this.setData(res.data);
//挂载每个权限类⽬的权限
this.setPermissTypePermissArrs();
}
})
.catch(err=>{ this.$(err.msg||ssage||s ||)});
},
methods:{
//取消选中状态
resetPermissItemState(){
this.permissionIds = [];
this.permissionArr.forEach(item=>{
this.$set(item,"checked",false);
});
/
/挂载每个权限类⽬的权限
this.setPermissTypePermissArrs();
},
//复选框变化的时候的回调函数
permissChange(item,e){
if(e.target.checked){antdesignvue 表格合计
this.$set(item,'checked',true)
}
else {
this.$set(item,'checked',false)
}
/
/重新挂载每个权限类⽬的权限
this.setPermissTypePermissArrs();
//获取选中的权限
},
//获取选中的权限
getCheckedPermiss(){
this.permissionIds = [];
this.permissionArr.forEach(item=>{
if(item.checked){
this.permissionIds.push(item.id);
}
})
},
//挂载每个权限类⽬的权限
setPermissTypePermissArrs(){
//顶级类⽬检测
this.permissionTreeData.forEach(item=>{
this.everyPermiss(item);
//设置权限类⽬的状态
this.setTreeDataState(item);
});
/
/设置权限类⽬的状态
this.clearAndSetCheckState();
},
//每个类⽬的权限集合的挂载
everyPermiss(data){
let permissArrs = [];
//权限挂载
data.permissArrs = this.itemCheck(data, permissArrs)
},
//获取每⼀个权限类⽬本⾝及其⼦级类⽬中的所有权限,并且挂载到⾃⾝属性上
itemCheck(data,permissArrs){
/
/挂载⾃⼰的权限
data.permission.forEach(item=>{
permissArrs.push(item);
});
data.children.forEach(item=>{
//挂载⼦级的权限
this.itemCheck(item,permissArrs);
//⼦级也要挂载
this.everyPermiss(item);
});
return permissArrs;
},
//设置权限类⽬的状态
setTreeDataState(item){
let checkState = {checkAll:false,checked:false};
//是否全选
checkState.checkAll = item.permissArrs.every(item1=>{return item1.checked === true});
//是否有选中,但没有全选
checkState.checked = item.permissArrs.some(item1=>{return item1.checked === true});
if(checkState.checkAll){
this.$set(item,'checkedAll',true);
this.$set(item,'halfChecked',false);
}
else {
if(checkState.checked){
this.$set(item,'checkedAll',false);
this.$set(item,'halfChecked',true);
}
else {
this.$set(item,'checkedAll',false);
this.$set(item,'halfChecked',false);
}
}
/
/⼦级递归调⽤
item.children.forEach(item1=>{this.setTreeDataState(item1)})
},
//清空之前的权限类⽬选中状态在设置新的选中状态
clearAndSetCheckState(){
//清楚选中状态
this.checkedKeys={
checked:[],
halfChecked:[]
};
let checked = [];
let halfChecked = [];
//设置新的选中状态
this.permissionTreeData.forEach(item=>{
this.setNewCheckState(item,checked,halfChecked)
});
this.$set(this.checkedKeys,'checked',checked);
this.$set(this.checkedKeys,'halfChecked',halfChecked);
},
//设置新的选中状态
setNewCheckState(data,checked,halfChecked){
//全选状态
if(data.checkedAll){
checked.push(data.id);
}
else {
//部分选中状态
if(data.halfChecked){
halfChecked.push(data.id);
}
}
//⼦级递归调⽤
data.children.forEach(item=>{ this.setNewCheckState(item,checked,halfChecked)})
},
//点击权限类⽬
select(key){
this.permissionChecks = [];
this.permissionArr.forEach(item=>{
if(item.permission_type_id === key){
this.permissionChecks.push(item);
}
})
},
//点击权限类⽬前⾯的checkbox 只操作全选中和未选中状态半选状态不负责
checkBoxCheck(checkedState,{checked}){
if(!checked){
let surplusPermissTypeIdsChecked = [];
let surplusPermissTypeIdsHalf = [];
let permissTypeItems = [];
//1.获取全部的权限类⽬id中除了全选的类⽬权限id之外,剩余的权限类⽬
surplusPermissTypeIdsChecked=  at(this.permissTypeIds).filter(function(v, i, arr) { return arr.indexOf(v) === arr.lastIndexOf(v);
});
//2.获取全部的权限类⽬id中除了全选和半选的类⽬权限id之外,剩余的权限类⽬
surplusPermissTypeIdsHalf=  at(surplusPermissTypeIdsChecked).filter(function(v, i, arr) { return arr.i
ndexOf(v) === arr.lastIndexOf(v);
});
if(surplusPermissTypeIdsHalf.length>0){
//根据权限类⽬id查权限类⽬
this.useIdFindPermissType(surplusPermissTypeIdsHalf,permissTypeItems);
permissTypeItems.forEach(item=>{
//重置没有在选中也没有在全选中的权限类⽬的状态及其所属的权限的状态
});
}
}
/
/  // // checkedState.checked⾥⾯对应的key为权限类⽬的id
//  // //全部选中的类⽬
else {
if(checkedState.checked.length>0){
checkedState.checked.forEach(key=>{
this.permissionTreeData.forEach(item2=>{
//查权限类⽬的选中状态并且设置其中所包含的权限集合的选中状态为true
this.findPermissChecked(key,item2);
});
});
}
}
//  重新挂载每个权限类⽬的权限
this.setPermissTypePermissArrs();
},
//根据权限类⽬id查权限类⽬
useIdFindPermissType(ids,permissTypeItems){
ids.forEach(id=>{
this.permissionTreeData.forEach(item2=>{
this.useIdFindPermissItem(item2,id,permissTypeItems);
})
});
},
//根据权限类⽬id和权限类⽬,查需要操作的权限类⽬
useIdFindPermissItem(data,id,permissTypeItems){
if(data.id === id){
permissTypeItems.push(data);
}
data.children.forEach(item=>{
this.useIdFindPermissItem(item,id,permissTypeItems);
})
},
/
/重置没有在选中也没有在全选中的权限类⽬的状态及其所属的权限的状态
resetPermissSatate(data){
data.permissArrs.forEach(item=>{
this.$set(item,'checked',false);