element ui 树形-懒加载-表格-多选 勾选问题

element ui树形表格如下:

element ui 树形-懒加载-表格-多选 勾选问题_第1张图片

它的数据格式为:使用children字段来存放子级数据

      tableData: [
        {
          id: 1,
          date: "2016-05-02",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1518 弄",
        },
        {
          id: 2,
          date: "2016-05-04",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1517 弄",
        },
        {
          id: 3,
          date: "2016-05-01",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1519 弄",
          children: [
            {
              id: 31,
              date: "2016-05-01",
              name: "王小虎",
              address: "上海市普陀区金沙江路 1519 弄",
            },
            {
              id: 32,
              date: "2016-05-01",
              name: "王小虎",
              address: "上海市普陀区金沙江路 1519 弄",
            },
          ],
        },
        {
          id: 4,
          date: "2016-05-03",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1516 弄",
        },
      ],

element ui 树形&懒加载 表格如下:

默认是不请求子级数据的,当点击下拉icon时再发起请求

element ui 树形-懒加载-表格-多选 勾选问题_第2张图片

 完整代码:

DOM:  需注意以下属性

        row-key="id"

        lazy

        :load="load"

        :tree-props="{

          children: 'children',

          hasChildren: 'hasChildren',

        }"

  
    
    
    
    
    
    
  

数据:就是普通的数组,没有子级数据的概念

      tableData1: [
        {
          id: 1,
          date: "2016-05-02",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1518 弄",
        },
        {
          id: 2,
          date: "2016-05-04",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1517 弄",
        },
        {
          id: 3,
          date: "2016-05-01",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1519 弄",
          hasChildren: true,
        },
        {
          id: 4,
          date: "2016-05-03",
          name: "王小虎",
          address: "上海市普陀区金沙江路 1516 弄",
        },
      ],

懒加载事件:

    load(tree, treeNode, resolve) {
     // 这里发请求,请求当前点击的子级数据data,然后交给resolve处理,就可以正确展示子级数据
      setTimeout(() => {
        resolve(data);
      }, 300);
    },

发现树形懒加载多选表格有两个问题:

1、勾选父级时子级不会勾选上

一般我们实现表格多选功能是这样的:这里不再使用这种方式

     
    

 第一步:需要我们手动写个勾选表头和勾选列

        
          
          
          
          
        

第二步: 定义数据

    checkAllDetail: false,
    isIndeterminate: false,

第三步:编写handleCheckAllDetail、handleCheckDetail函数,

每次勾选时要做的事:

处理全选、半选状态;

用个数组处理勾选行的数据,勾选时将数据存起来,取消勾选时将数据删除;

若勾选父级时,将子级的数据也全部勾选;取消勾选反之;

若勾选子级时,也要计算父级是否应该勾选上;

第四步:点击下拉icon时也要数据子级数据的勾选状态

这里涉及到一个很重要的问题:如何拿到子级数据:先给表格绑定ref属性

this.$refs.mulTable.store.states.lazyTreeNodeMap这个可以取到所有展开的子级数据

数据格式为:{父级id1: [{子数据1}, {子数据2}],  父级id2: [{子数据}] }

 举个例子:当勾选单个数据时如何处理

 // 单条数据的勾选操作
    handleCheckDetail(row, val) {
      // 如果勾选的是子级数据:那么要计算子级决定父级勾选状态
      if (row.parent) {
        let parentId = row.parent; //父级id
        let loadChildData = this.$refs.mulTable.store.states.lazyTreeNodeMap; // 所有展开项的懒加载数据
        let parentItem = loadChildData[parentId]; //当前父级下的所有子数据
        // 判断当前下的所有子数据是否全部勾选上了
        let checked = parentItem?.every(function (currentValue, index, arr) {
          return currentValue.checked;
        });
        // 设置父级数据的勾选状态
        for (let i = 0; i < this.list.length; i++) {
          if (this.list[i].id === parentId) {
            this.$set(this.list[i], "checked", checked);
          }
        }
        // 勾选则将id添加进去,否则删除id【selectArrIds是用来存放勾选数据的id的数组】
        if (checked) {
          this.selectArrIds.push(parentId);
        } else {
          let index = this.selectArrIds.indexOf(parentId);
          if (index !== -1) {
            this.selectArrIds.splice(index, 1);
          }
        }
      } else {
        // 如果当前点击的是父级数据:那么父级决定子级状态
        let loadChildData = this.$refs.mulTable.store.states.lazyTreeNodeMap; // 所有展开项的懒加载数据
        let datas = loadChildData[row.id]; //当前父级下的所有子数据
        // 将父级的勾选状态同步给子级
        datas?.forEach((item) => {
          this.$set(item, "checked", val);
        });
        // 勾选则将id添加进去,否则删除id【selectArrIds是用来存放勾选数据的id的数组】
        if (val) {
          this.selectArrIds.push(row.id);
        } else {
          let index = this.selectArrIds.indexOf(row.id);
          if (index !== -1) {
            this.selectArrIds.splice(index, 1);
          }
        }
      }
      // 计算半选和全选状态
      let totalCount = this.list.length;
      this.checkAllDetail =
        totalCount === this.selectArrIds.length ? true : false;
      this.isIndeterminate =
        this.selectArrIds.length > 0 && this.selectArrIds.length < totalCount;
    },

 当勾选全选checkbox时如何处理

    handleCheckAllDetail(val) {
      this.isIndeterminate = false;
      let setIds = [];
      this.list.forEach((item, index) => {
        if (
          val &&
          this.selectArrIds.indexOf(item.id) === -1
        ) {
          setIds.push(item.id);
        }
      });
      if (val) {
        this.selectArrIds = setIds;
      } else {
        this.selectArrIds = [];
      }
      // 若有展开项,则将子级也勾选上
      this.setChildCheck(val);
    },

 setChildCheck方法:

    // 设置子级的数据勾选状态
    setChildCheck(val) {
      let loadChildData = this.$refs.mulTable.store.states.lazyTreeNodeMap;
      if (Object.keys(loadChildData).length > 0) {
        let keys = [];
        for (let key in loadChildData) {
          keys.push(key);
        }
        for (let i = 0; i < keys.length; i++) {
          let datas = loadChildData[keys[i]];
          datas?.forEach((item) => {
            // 按父级的勾选状态去控制子级的勾选状态
            let isChecked;
            for (let i = 0; i < this.list.length; i++) {
              if (this.list[i].id === item.parent) {
                isChecked = this.list[i].checked;
              }
            }
            this.$set(item, "checked", isChecked);
          });
        }
      }
    },

效果如下:

element ui懒加载树形表格-勾选

2、对子级数据进行删除、修改、添加操作时,不会更新子级数据

这个问题目前还没实现,但是估计也是通过this.$refs.mulTable.store.states.lazyTreeNodeMap处理数据,稍后更新~~

PS:后来发现了另外一个非常棒的UI库,可以考虑使用~~

vxe-table v4

element ui 树形-懒加载-表格-多选 勾选问题_第3张图片

你可能感兴趣的:(element,ui,vue.js,前端,javascript)