zoukankan      html  css  js  c++  java
  • vue使用elementUi制作懒加载多选表格

    此文章为原创文章,原文地址:https://www.cnblogs.com/eagle1098/p/13982996.html

    制作此表格的技术难点在于多选框的状态设置,因为element默认全选不能选择懒加载出来的数据行,而且子数据行也不能影响父标题行的选择状态,这些工作都要开发者自己想办法解决。

    首先,说一下全选框选中懒加载子数据行的方法。

    1)给table增加全选事件

    @select-all="tableSelectAll"

    2)在对应函数中根据全选框状态,对存储被选数据数组进行处理,清空半选状态数组,因为全选行为会清除所有半选状态。

    tableSelectAll(selection) {
         //清空半选数组,此数组请提前在data中定义
          this.checkIndeRow = [];
          //获得子数据对象
          let children = this.$refs.myTable.store.states.lazyTreeNodeMap;
          //已选数组
          let select = this.$refs.myTable.store.states.selection;
          //全选状态
          let isAllSelect = this.$refs.myTable.store.states.isAllSelected;
          if (isAllSelect) {
            for (let item in children) {
              children[item].forEach((d, i) => {
                if (select.indexOf(d) == -1) {
                  select.push(d);
                }
              });
            }
          } else {
            this.$refs.myTable.store.states.selection = [];
          }
        }

    然后,说说懒加载子数据的选择对全选框和父选择框的影响。element没有提供父选框的半选功能,我们只能自己记录哪些父选框是半选状态,然后去修改它们的class。

    1)给table添加单独选择事件

    @select="tableSelect"

    2)单独点击选择框,首先根据子数据行找到父数据行,然后判断父数据行下面的所有子数据行是否都被选择了,如果都被选择了则父数据行被加入总选择数组,把父数据行移出半选数组;如果子数据行只被部分选择则父数据行被移出选择数组,这样做的目的是改变全选框的状态,并且改变父数据行选择框的状态为半选,把父数据行存入半选数组;如果子数据行全都是未选中状态,把父数据行移出选择数组和半选数组。

    tableSelect(selection, row) {
      let states = this.$refs.myTable.store.states;
      let children = states.lazyTreeNodeMap[row.id];
      let select = states.selection;
      //如果被点击的是标题行
      //因为表中存在标题行,所以设置一个type参数,0为标题行
      if (row.type == 0) {
        // 如果半选数组中有被点击行,则半选状态肯定被取消
        let keyIndeRow = this.checkIndeRow.indexOf(row);
        if (keyIndeRow >= 0) {
          this.checkIndeRow.splice(keyIndeRow, 1);
        }
        if (row.hasChildren) {
          //如果选择数组中没有此行数据,则将其子数据都加入选择数组
          if (selection.indexOf(row) >= 0) {
            for (let item in children) {
              if (select.indexOf(children[item]) == -1) {
                select.push(children[item]);
              }
            }
          } else {
          //如果选择数组中已有此行数据,则将其子数据都移出选择数组
            for (let item in children) {
              let key = select.indexOf(children[item]);
              if (key >= 0) {
                select.splice(key, 1);
                let child = states.lazyTreeNodeMap[children[item].id];
              }
            }
          }
        }
      }
      //如果被点击的是子行
      if (row.type == 1) {
        //找到此子条目的父条目
        let parentId = '';
        for (let id in states.lazyTreeNodeMap) {
          states.lazyTreeNodeMap[id].forEach((d, i) => {
            if (d == row) {
              parentId = id;
            }
          });
        }
        let sum = 0;
        //计算子数据行有多少已经被选中
        states.lazyTreeNodeMap[parentId].forEach((d, i) => {
          if (selection.indexOf(d) >= 0) {
            sum++;
          }
        });
        //得到父行数据对象
        let parentObj = states.data.filter((d, i, arr) => {
          return d.id == parentId;
        });
        let parentNode = parentObj[0];
        // 如果已选条目中已经有了所有子条目,则目录应被选中
        if (sum === states.lazyTreeNodeMap[parentId].length) {
          if (select.indexOf(parentNode) == -1) {
            select.push(parentNode);
          }
          let key = this.checkIndeRow.indexOf(parentNode);
          if (key >= 0) {
            this.checkIndeRow.splice(key, 1);
          }
        } else if (sum > 0) {
          // 如果只有部分子条目,则目录应被半选
          // 从selection中删除,用来改变全选按钮的状态为半选
          let key = select.indexOf(parentNode);
          if (key >= 0) {
            select.splice(key, 1);
          }
          this.checkIndeRow.push(parentNode);
        } else {
          // 如果没有子条目,则目录应不选
          let key = select.indexOf(parentNode);
          if (key >= 0) {
            select.splice(key, 1);
          }
          let keyIndeRow = this.checkIndeRow.indexOf(parentNode);
          if (keyIndeRow >= 0) {
            this.checkIndeRow.splice(keyIndeRow, 1);
          }
        }
      }
    }

    在修改element默认的css时要注意,在组件自己scoped的样式之外新建一个不带scoped的style区域,需要覆盖的样式写在一个自己的父样式中,以避免污染全局。
    修改选择框为半选状态需要自己手动设置,方法如下:

    //给table组件添加:cell-class-name="setTableClass"属性
    setTableClass({ row, column, rowIndex, columnIndex }) {
      if (
        this.checkIndeRow.length > 0 &&
        this.checkIndeRow.indexOf(row) >= 0 &&
        columnIndex == 0
      ) {
        return 'el-checkbox__input is-indeterminate';
      }
    }

    修改后若出现选择框的高度变化问题,设置如下:

    .el-checkbox,
    .el-checkbox__input {
      display: revert;
    }

    改变懒加载展开箭头位置的方法:只要列属性中type的值是expand,就会添加展开箭头,如果不写type属性,则type的默认值就是expand,所以在不想加箭头的列添加type属性而不赋值,这样该列就不会添加展开箭头。

    手动控制懒加载方法:也就是不点击element指定的箭头,点击其他部位,比如点击行进行懒加载。这个功能需要对element源码进行分析,经过分析后知道,调用

    this.$refs.table1.store.loadOrToggle(row)即可打开或关闭此行下的子数据行,其中table1为表格ref值。

    此文章为原创文章,原文地址:https://www.cnblogs.com/eagle1098/p/13982996.html

  • 相关阅读:
    单词接龙
    洛谷 P1015 回文数
    洛谷 P1012 拼数
    codevs 2780 ZZWYYQWZHZ
    专项练习之字符串
    模拟题1
    专项训练之线段树
    复习题之求后序遍历
    复习题之二叉树的遍历
    Hdu 3037 Saving Beans(Lucus定理+乘法逆元)
  • 原文地址:https://www.cnblogs.com/eagle1098/p/13982996.html
Copyright © 2011-2022 走看看