element-ui tree控件 当父节点下的子节点都被选中时,新增子级也被选中

1,968 阅读2分钟

1.问题描述:

用tree控件显示权限列表时,当某个用户的父权限下的子权限之前是全部选中时,新增的子节点会自动选中

我新增一个子节点并且没有给管理员这个权限

但是!他自动勾选了!!!

2.问题产生的原因:

当一个父节点下的子节点被全选中时,父节点id也会被记录在已选的权限中,当我们把含有父节点id传给后端,再请求渲染数据时,tree控件的setCheckedKeys()方法会把请求过来的权限数组全部渲染出来,并且tree控件的check-strictly属性默认为false,也就是遵循父子互相关联,我们来看官方文档说明

父子互相关联的情况下,父节点被选中,其下的所有子节点自然也会被选中

3.解决办法

3.1取消父子互相关联

设置check-strictly属性为true,但是会影响全选,并且传给后端的时候,父节点没勾选就不会有父节点id

3.2过滤父节点id再渲染

<!-- 节点树 -->
<el-form-item label="选择节点" prop="rules">
   <el-tree ref="tree" :data="treeData" show-checkbox node-key="id"> </el-tree>
</el-form-item>

treeData: [],// 权限树
hasChecked: [],// 用户已有权限

showDrawer(){
  let that = this;
  that.drawer.visible = true;
  // 获取所有权限列表
  getTreeData().then(res=>{
  	if(res.code == 200){
   	  that.treeData = res.data.tree
    }else{
      that.$message.error(res.msg)
    }
  });
  
  // 获取用户权限
  getUserRules().then(res=>{
    if(res.code == 200){
      // 如果该用户已有权限
      if(res.data.checked){
        that.hasChecked = res.data.checked;
        let newArr = [];
        that.hasChecked.forEach(item=>{
          // item是已有的权限id,将已有的权限id与全部的id进行匹配,找到它的父id并删除
          that.checked(item, that.treeData, newArr)
        });
        that.hasChecked = newArr;
        // 渲染
        this.$refs['tree'].setCheckedKeys(that.hasChecked);
      }
    }
  })
},

// 检测id是否是父级id,并将子级id过滤,运用递归
checked(id, data, newArr){
  data.forEach(item=>{
  	// 在数组中查找属于这个id的item
    if(item.id == id){
     // 如果item没有子级或者暂时为空,说明它不是父节点或者暂时不是
     if(item.children == undefined || item.children.length < 1){
     	newArr.push(item.id);
     }
    }else{
     // 如果有子级,继续往下查找,检查这个id是否是子节点id
     if(item.children != undefined && item.children.length != 0){
       this.checked(id, item.children, newArr)
     }
    }
  })
},

4.总结

4.1 如果后端不需要你传父级id,直接用check-strictly属性就可以,需要传的话就用上面的方式,并且在回传的时候,将父级id和子级id合并传过去

需要注意的是,tree控件只有在子节点全部被选中时,父节点才是选中状态

这是就需要用getHalfCheckedKeys方法了

let checked = that.$refs.tree.getCheckedKeys();
let halfChecked = that.$refs.tree.getHalfCheckedKeys();
let rules = [];
that.apiparams.rules = rules.concat(halfChecked,checked)

这样就可以了