2021-03-13 el-tree 解决全选后所有子节点会被选

2021-03-13  本文已影响0人  jinya2437

前端调用树状结构,传递参数给后台。要求父节点必传。举例子:

data:[
  {id:1,name:'父节点',children:[
    { id:2,name:'子节点2',children:[]},
    { id:3,name:'子节点3',children:[]}]
  }
]

新增场合,当选中【子节点2】时候,要求传递参数ids:[1,2]。id=1的父节点的id也传递。代码如下:

//新增
<el-tree ref="tree" :data="treeData" show-checkbox node-key="id" :props="defaultProps" :default-expand-all="true"></el-tree>
methods:{
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          this.form.moduleId = this.menuItem.moduleId
          // 注意点:传递参数(获取了父子节点)
          this.form.menuIds = this.$refs.tree.getCheckedNodes(false,true).map(item=>item.id)
          roleApi.add(this.form).then(res=>{
            ....
          })
        } else {
          return false
        }
      });
    }
}

编辑场合,接口获取form.menuIds=[1,2]赋值给树状默认选中。页面效果[1,2,3]所有子节点都选中,可新增没选中id=3。解决全选后所有子节点会被选中,办法如下所示。

<el-tree ref="tree" :data="treeData" show-checkbox node-key="id"
                     :props="defaultProps" :default-expand-all="true"
                     :default-checked-keys="form.menuIds"></el-tree>
methods:{
    getRoleFn() {
      let id = this.$route.query.id
      roleApi.get(this.menuItem.moduleId,id).then(res=>{
        if(res.code==0){
          this.form.menuIds = res.data.menuIds
          this.form.id = res.data.id
          this.queryTree()
        }else{
          this.$message({type:'error',message:res.message})
        }
      })
    },
    queryTree() {
      menuApi.tree(this.menuItem.moduleId).then(res=>{
        if(res.code==0){
          this.treeData = res.data
          let newArr = []
          if (this.form.menuIds && this.form.menuIds.length !== 0) {
            this.form.menuIds.forEach(idItem => {
              this.checked(idItem, this.treeData, newArr)
            });
            // 注意点:不包含父节点id的集合
            this.form.menuIds = newArr
          }
        }else{
          this.$message({type:'error',message:res.message})
        }
      })
    },
    //重点 递归 去掉 父节点
    checked(id, data, newArr) {
      data.forEach(item => {
        if (item.id == id) {
          if (item.children && item.children.length == 0) {
            newArr.push(item.id);
          }
        } else {
          if (item.children != null && item.children.length != 0) {
            this.checked(id, item.children, newArr);
          }
        }
      });
    }
}

查询场合展示表格列表,鼠标悬浮在【角色权限】栏目中el-popover显示树状,以及角色权限勾选详情

<el-tree
                          :ref="'tree'+scope.$index"
                          :default-expand-all="true"
                          :data="treeData"
                          check-strictly //注意点1 父子无相关,后台传递【1,2】一个值对应一个勾,不存在父子关系
                          accordion      //注意点2 
                          show-checkbox
                          node-key="id"
                          :props="defaultProps"
                          :default-checked-keys="scope.row.menuIds"
                          class="padding-20"
                          @check="checkFn(...arguments,scope.$index,scope.row.menuIds)"
                  >
                  </el-tree>
methods:{
    // 列表场合 不能操作节点
    checkFn(data,b,index,menuIds) {
        if(menuIds.find(item=>item==data.id)){
          this.$refs[`tree${index}`].setChecked(data,true,true)
        }else{
          this.$refs[`tree${index}`].setChecked(data,false,true)
        }
      },
}

疑问点:编辑场合使用查询该方法不是更好么,不用写递归....
回答:如果使用查询该办法,则当您选中父节点 id=1时,子节点[2,3]没有选中,用户体验不合理。项目里父节点下子节点有【30到40】个,用户点击31次么.....

上一篇下一篇

猜你喜欢

热点阅读