在权限中父子集不关联,一开始,我以为default-checked-keys值不对,最后看了文档,原来是check-strictly被开启了
<el-tree ref="menu" :data="permissionSelectList" :default-checked-keys="permissionArr" :props="defaultProps" show-checkbox node-key="permissionId" />
首先去掉了,然后父子联动没有问题了,但是,又出现了新的问题,主要病症出现在半选的父节点数据上,接口要求是半选的节点也要提交的,但是点击修改,回显的时候,因为提交了半选的数据,此时,selected是1,勾选的状态,导致回显都是被选中的状态。
修改方案:回显过滤一下数据
1、过滤menu,selected为1,permissionId存在a数组中
// 递归获取 已选择的权限 function getSelectSermissions(list) { const selectArr = []; function asyncSelect(list) { return list.filter((item) => { if (item.selected && item.selected === "1") { selectArr.push(item.permissionId); } // 判断是否有子组件 if (item.children && item.children.length) { asyncSelect(item.children); } return true; }); } asyncSelect(list); return selectArr; }
2、过滤menu的children,selected为0,把父节点的ID取出来存在b数组中
function getSelectSermissions2(list) { const selectArr = []; function asyncSelect(list) { return list.filter((item) => { if (item.children && item.children.length) { let obj = item.children.find(subItem => subItem.selected === '0') if(obj){ selectArr.push(item.permissionId); } asyncSelect(item.children); } return true; }); } asyncSelect(list); return selectArr; }
点击编辑,回显权限树,由于保存的时候,半选的节点也传给后端,回显的时候,select则为1。所以在detailFn事件中添加过滤方法,把子节点为0的父节点删除掉。
detailFn(roleId) { let { permissionTree } = res //子集中select有0的父级id过滤出来 let x = getSelectSermissions2(permissionTree);
//['100', '100400', '100500'] //树中select为1的过滤出来 let y = getSelectSermissions(permissionTree);
//['100', '100100', '100100100', '100100200', '100100300', '100100400', '100100500', '100100600', '100100700', '100200', '100200100', '100200300', '100300', '100300100', '100300200', '100300300', '100400', '100400100', '100400200', '100400300', '100400400'] console.log(x,y) // 树中select为1的y数组中删除掉 子集中select有0的父级id this.permissionArr = y.filter(item=>!x.includes(item))
//['100100', '100100100', '100100200', '100100300', '100100400', '100100500', '100100600', '100100700', '100200', '100200100', '100200300', '100300', '100300100', '100300200', '100300300', '100400100', '100400200', '100400300', '100400400'] return true; },
逻辑是这样的,但是写了两个方法进行过滤,确实繁琐,最终,简化方法如下:
function getSelectSermissions(list) { const selectArr = []; function asyncSelect(list) { return list.filter((item) => { if (item.selected && item.selected === "1") { selectArr.push(item.permissionId); } // 判断是否有子组件 if (item.children && item.children.length) { // 查询子节点为0的父节点 let obj = item.children.find(subItem => subItem.selected === '0') if(obj){
// 通过obj的条件有100,100400,100500 if(selectArr.includes(item.permissionId)){// selectArr确认包含子节点为0的父节点 itme.permissionId的值是否有100,100400,100500 // 数组中删除100,100400 selectArr.splice(selectArr.findIndex(lastItem => lastItem === item.permissionId), 1) } } asyncSelect(item.children); } return true; }); } asyncSelect(list); return selectArr; }
调用
let arr = [{ permissionId: "100", selected: "1", children:[{ permissionId: "100100", selected: "1", },{ permissionId: "100200", selected: "1", },{ permissionId: "100300", selected: "1", },{ permissionId: "100400", selected: "1", children:[{ permissionId: "100400100", selected: "1", },{ permissionId: "100400200", selected: "0", }] },{ permissionId: "100500", selected: "0", children:[{ permissionId: "100500100", selected: "0", },{ permissionId: "100500200", selected: "0", }] }] }] let x = getSelectSermissions(arr); console.log(x) //['100100', '100200', '100300', '100400100']
补充:传参数给后端的数据,getHalfCheckedNodes,getCheckedKeys,具体查看element文档
let menus = [] // 得到半选的父节点数据 this.$refs.menu.getHalfCheckedNodes().forEach(function (data, index) { menus.push({ permissionId: data.permissionId }); }); // 得到选中的节点 this.$refs.menu.getCheckedKeys().forEach(function (data, index) { menus.push({ permissionId: data }); })