关于el-tree属性结构,父级选中控制子级的情况

最近项目中有一个需求如下:
后端返回一个树形结构的数据.返回的数据中已有设置diasbled的属性
1.任意一级别父节点选中,其下所有的子节点都需要设置disabled属性为true.且原父节点下已有选中的子节点,需要将已选中的子节点设置成不选中
2.任意一级别父节点取消选中,其下所有的子节点都需要将disabled属性设置成false,但是需要排除掉接口返回数据中已经是disabled数据
3.后端中返回数据中已有disabled:true属性的,不管其任意父级节点选中与否,都不会影响到他!

代码如下:

1. 后端返回的数据:

data() {
    return {
      realyData: [
        {
          id: 1,
          parentId: 0,
          label: "一级 2",
          isLock: false,
          disabled: false,
          children: [
            {
              id: 3,
              parentId: 1,
              label: "二级 2-1",
              isLock: false,
              disabled: false,
              children: [
                {
                  id: 4,
                  parentId: 3,
                  label: "三级 3-1-1",
                  isLocked: false,
                  disabled: false,
                },
                {
                  id: 5,
                  parentId: 3,
                  label: "三级 3-1-2",
                  isLock: true,
                  disabled: true,
                },
              ],
            },
            {
              id: 2,
              parentId: 1,
              label: "二级 2-2",
              isLock: false,
              disabled: false,
              children: [
                {
                  id: 6,
                  parentId: 2,
                  label: "三级 3-2-1",
                  isLock: false,
                  disabled: false,
                },
                {
                  id: 7,
                  parentId: 2,
                  label: "三级 3-2-2",
                  isLock: false,
                  disabled: false,
                },
              ],
            },
          ],
        },
      ],
      defaultProps: {
        children: "children",
        label: "label",
      },
    };
  },

2.el-tree绑定的数据

 <el-tree
      :data="realyData" 
      ref="opentree"
      show-checkbox       // 显示多选框
      node-key="id"       // 唯一标识
      default-expand-all  // 默认展开全部
      check-strictly      // 父子不互相关联
      @check="check"      // 当复选框被点击的时候触发
    >
    </el-tree>

3.数据的处理

  methods: {
    // check方法查阅饿了么的文档 一共俩参数
    check(data, allObj) {
      // 拿到当前已经选中的id
      const { checkedKeys } = allObj;
      // 当前点击节点是否被选中
      let ischecked = checkedKeys.includes(data.id);
      // 将其所有子节点已经勾选的 重置为 未勾选状态
      this.resetCheckEn(ischecked, data.children);
      // 设置disabled --> 这里传递进去的参数是整个el-tree绑定的data
      this.findNodeFn(data.id, ischecked, this.realyData);
      // 拿到所有节点的key值数组
      const checkedArr = this.$refs.opentree.getCheckedKeys();
      // 名称显示
      const nodes = this.$refs.opentree.getCheckedNodes();
    },

    // 点击父节点--置空已选的下级子节点
    resetCheckEn(isChecked, arr) {
      if (Array.isArray(arr)) {
        arr.forEach((item) => {
          /**
           * isLock的值与原后端返回的disabled的值相同,如果后端没有返回,可以自己递归添加上去
           * isLock用来标识后端返回的原始数据是否又已经禁止操作的
           * isLock == true 原始数据已经禁止任何操作的 反之 原来数据可以做操作的
           * */
          // 所以需要拿到原来没有禁止的数据
          if (!item.isLock) {
            if (isChecked) {
              // isChecked === true => 父级已经勾选中了
              // 所以这里需要给自己设置成不选中
              this.$refs.opentree.setChecked(item.id, !isChecked); 

            } else {
             
              // 父节点没有勾选 => 也需要给子节点设置成不选中
              this.$refs.opentree.setChecked(item.id, isChecked);
            }
          }
          // 递归 => 给当前点击节点的所有子节点设置成不勾选状态
          if (item.children) {
            this.resetCheckEn(isChecked, item.children);
          }
        });
      }
    },

    /**
     * 寻找当前点击的数据以及判断其是否有子节点
     * faId=> 父节点的id
     * faIsCheck => 父节点是否被选中
     * arr => 当前el-tree绑定的数据源
     * */
    findNodeFn(faId, faIsCheck, arr) {
      if (Array.isArray(arr)) {
        arr.forEach((el) => {
          // 遍历当前treeData 拿到与当前点击的id的数据
          if (el.id == faId) {
            // 找到当前点击的数据,将其子节点设置disable属性
            this.setDisabledFn(el.children, faIsCheck, faId);
          } else {
            // 如果不是一级数据,递归往下找其子级(二级,三级,....)的数据,直到找到当前的数据
            if (el.children) {
              this.findNodeFn(faId, faIsCheck, el.children);
            }
          }
        });
      }
    },

    // 点击父节点--给下级所有的子节点是否设置disabled
    /**
     * arr --> 当前点击的父节点下的children属性数据(子节点的数据)
     * faIsCheck --> 父节点是否被选中
     * */
    setDisabledFn(arr, faIsCheck) {
      if (Array.isArray(arr)) {
        arr.forEach((el) => {
          // 父节点被勾选 子节点disable的属性设置为true
          if (faIsCheck) {
            el.disabled = true;
          } else {
            /**
             * 父节点取消勾选的,需要排除原来就禁止操作的数据
             * 将非禁止的子节点数据disable的属性设置为false
             */
            if (!el.isLock) {
              el.disabled = false;
            }
          }
          // 如果子节点下还有子节点的:
          //递归调用自己,直到将所有子级数据的disable属性都设置完成
          if (el.children) {
            this.setDisabledFn(el.children, faIsCheck);
          }
        });
      }
    },
  },

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值