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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM