el-tree 勾选子节点影响父节点的问题

一、代码结构

有一天小编在改一个 el-tree 的问题,代码是类似下方的结构:

<template>
  <div>
    <el-tree
      :data="treeData"
      show-checkbox
      node-key="id"
      ref="tree"
      @check-change="handleCheckChange"
    ></el-tree>
  </div>
</template>

<script>
export default {
  data() {
    return {
      treeData: [
        {
          id: 1,
          label: '一级 1',
          sts: 0, // 初始状态为0
          children: [
            {
              id: 4,
              label: '二级 1-1',
              sts: 0, // 初始状态为0
            },
          ],
        },
        {
          id: 2,
          label: '一级 2',
          sts: 0, // 初始状态为0
          children: [
            {
              id: 5,
              label: '二级 2-1',
              sts: 0, // 初始状态为0
              children: [
                {
                  id: 6,
                  label: '三级 2-1-1',
                  sts: 0, // 初始状态为0
                },
              ],
            },
          ],
        },
        {
          id: 3,
          label: '一级 3',
          sts: 0, // 初始状态为0
          children: [
            {
              id: 7,
              label: '二级 3-1',
              sts: 0, // 初始状态为0
            },
            {
              id: 8,
              label: '二级 3-2',
              sts: 0, // 初始状态为0
            },
          ],
        },
      ],
    };
  },
  methods: {
    handleCheckChange(data, checked, indeterminate) {
      this.updateNodeStatus(data, checked);
    },
    updateNodeStatus(node, checked) {
      node.sts = checked ? 1 : 0;
      if (node.children) {
        node.children.forEach(child => {
          this.updateNodeStatus(child, checked);
        });
      }
    },
  },
};
</script> 

二、定位问题

经定位,发现在使用 check-change 方法监听的时候,假如当前节点的树都未选中,取消选中其中的某一个子节点,如下图:
在这里插入图片描述
此时,check-change函数会被触发三次:(1)子节点自己改变(2)子节点的父节点有所改变(3)子节点的祖父节点也有所改变;所以此时 updateNodeStatus 函数会被调用三次,并且将当前节点下的child都回置父节点的选中状态,从而导致“一级1”整个节点都未选中。

思路1、check-strictly

该功能是:在显示复选框的情况下,是否严格的遵循父子不互相关联的做法,默认为 false,设置为true的话,父子节点完全不会联动,显然不是小编想要的效果;

最终解决办法:

1、在用户操作树的时候不做任何修改数据的操作;
2、在用户点击保存按钮时,通过 getCheckedKeys 方法获取所有当前选中的节点id数组;然后通过递归遍历 treeData 原数组,将包含在 getCheckedKeys 数组中的节点sts字段置为相对应的状态即可。
<template>
  <div>
    <el-tree
      :data="treeData"
      show-checkbox
      node-key="id"
      ref="tree"
    ></el-tree>
  </div>
</template>

<script>
export default {
  data() {
    return {
      treeData: [
        {
          id: 1,
          label: '一级 1',
          sts: 0, // 初始状态为0
          children: [
            {
              id: 4,
              label: '二级 1-1',
              sts: 0, // 初始状态为0
            },
          ],
        },
        {
          id: 2,
          label: '一级 2',
          sts: 0, // 初始状态为0
          children: [
            {
              id: 5,
              label: '二级 2-1',
              sts: 0, // 初始状态为0
              children: [
                {
                  id: 6,
                  label: '三级 2-1-1',
                  sts: 0, // 初始状态为0
                },
              ],
            },
          ],
        },
        {
          id: 3,
          label: '一级 3',
          sts: 0, // 初始状态为0
          children: [
            {
              id: 7,
              label: '二级 3-1',
              sts: 0, // 初始状态为0
            },
            {
              id: 8,
              label: '二级 3-2',
              sts: 0, // 初始状态为0
            },
          ],
        },
      ],
    };
  },
  methods: {
    handleCheckChange(data, checked, indeterminate) {
      this.updateNodeStatus(data, checked);
    },
    updateNodeStatus(node, checked) {
      node.sts = checked ? 1 : 0;
      if (node.children) {
        node.children.forEach(child => {
          this.updateNodeStatus(child, checked);
        });
      }
    },
    updateSts(tree,chooseIds) {
		tree.forEach(node => {
			const isChosen = chooseIds.includes(node.id)
			node.sts = isChosen ? 1 : 0;
			if(node.children) {
				this.updateSts(node.children,chooseIds)
			}
		})
	},
    getTreeData() {
		let chooseIds = this.$refs.tree.getCheckedKeys();
		this.updateSts(this.treeData,chooseIds);
		console.log(this.treeData)
	}
  },
};
</script> 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值