需求背景
需要在角色管理中分配菜单,要求点击父级节点父节点选中子节点全部选中,父节点取消子节点全部取消选中;节点拥有子节点并且子节点中有选中则父节点选中,若子结点中没用被选中的父节点也取消选中。
dom
<el-tree
:data="treeData"
@check="checkTree"
show-checkbox
node-key="menuId"
default-expand-all
check-strictly
ref="tree"
:props="defaultProps"
></el-tree>
data
treeData:[]
defaultProps: {
children: "children",
label: "menuName"
}
methods
getMenuTree() {
//获取菜单
sysMenu({}).then(res => {
if (res.data.code == 0) {
this.tableData = res.data.data;
this.forEachTree(this.tableData, "");
console.log(this.tableData)
} else {
this.tableData = [];
}
});
},
forEachTree(list, str) {
list.forEach((item,index) => {
let idstr = str;
if (str) {
idstr += "-" + item.menuId;
} else {
idstr += "" + item.menuId;
}
item.pathId = idstr;
if (item.children && item.children.length > 0) {
this.forEachTree(item.children, idstr);
}
});
},
checkTree(val, el) {
console.log(val, el);
let checkList = el.checkedKeys;
if (el.checkedKeys.includes(val.menuId)) {
//选中当前点击节点
let list = this.setCheckTree([val]);
list = list.concat(val.pathId.split("-"));
list.forEach(item => {
if (!checkList.includes(item * 1)) {
//不在当前选中
checkList.push(item * 1);
}
});
} else {
//取消选中节点
let pathId = val.pathId.split("-");
pathId.pop();
pathId.pop();
let list=[]
el.checkedNodes.forEach(item=>{
if(item.pathId.split('-').includes(val.menuId+'')){//节点上级中是否有取消节点
list.push(item.menuId)
}
})
pathId.reverse().forEach(item=>{
let flag=false
let index=0
el.checkedNodes.forEach((item1,i)=>{
if(item1.parentId==item){
flag=true
}
if(item==item1.menuId){
index=i
}
})
if(!flag){//没有节点的parentId是当前item
list.push(item)
el.checkedNodes.splice(index,1)
}
})
list.forEach(item => {
if (checkList.includes(item * 1)) {
//不在当前选中
checkList.forEach((item1, index) => {
if (item1 == item) {
checkList.splice(index, 1);
}
});
}
});
}
this.$refs.tree.setCheckedKeys(checkList);
},
setCheckTree(arr) {
//获取当前&子集节点id数组
let list = [];
let forTree = item => {
item.forEach(el => {
list.push(el.menuId);
if (el.children.length > 0) {
forTree(el.children);
}
});
};
forTree(arr);
return list;
},