基於ElementUI中Table嵌套實現多選的示例代碼

前言:

寫這個是因為幫朋友修改項目中的bug
我也是第一次寫這個功能,有不對的希望大傢指正,如果看完有幫助點個贊!
代碼中關鍵是js中Tree的路徑查找這個核心,有不懂的自行百度
多瞭不說瞭,有需要的可以私信找我要代碼,來看下我怎麼實現的

思路:

從頭開始看這個需求,我們需要知道用到哪寫東西

1、表格Table
2、多選&全選
3、嵌套數據(下拉操作)

正好我們可以找下ElementUI官方文檔

找到瞭我們需要用到的API

  • 在嵌套數據的時候需要使用tree-props
  • 選中數據的時候使用toggleRowSelection

基本就以上這些能用到的可以開搞瞭

實現:

基於以上我們可以寫出HTML結構

<template>
 <div>
  <el-table
   ref="multipleTable"
   :data="tableData"
   style="width: 100%; margin-bottom: 20px"
   row-key="id"
   border
   default-expand-all
   :select-on-indeterminate="true"
   :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
   @select="rowSelect"
   @select-all="selectAll"
  >
   <el-table-column type="selection" width="55"> </el-table-column>
   <el-table-column prop="date" label="日期" width="180"> </el-table-column>
   <el-table-column prop="name" label="姓名" width="180"> </el-table-column>
   <el-table-column prop="address" label="地址"></el-table-column>
  </el-table>
 </div>
</template>

表格的多選我可以分為2項目,1個是正向選中,意思就是checkout為true的時候,2是反向取消就是checkout為false的時候,那下面我就來分析下這個正向選中和反向取消如何實現

一、正向選中

假設我有這樣的數據
以下面圖1片為例:
    在點擊子節點的時候我們需要把子節點的父節點和跟節點同時進行選中處理
    跟節點-父節點-子節點
    圖2是我data中聲明的數據,數據中包含isChecked是否被選中和children是否有子節點

現在我們正向選中思路明確瞭那我們怎麼來實現?

當我點擊子節點時候需要記錄子節點的父節點一直到跟節點,那我們就用到瞭Tree樹的概念

下面代碼用到瞭樹的回溯的思想,查找路徑使用先序遍歷,因為你不確定你點擊的是子節點是在哪個子樹上,
具體的Tree方法思想請百度一下;

treeFindPath(tree, func, path = []) {
   if (!tree) return [];
   for (const data of tree) {
    path.push(data);
    if (func(data)) return path;
    if (data.children) {
     const findChildren = this.treeFindPath(data.children, func, path);
     if (findChildren.length) return findChildren;
    }
    path.pop();
   }
   return [];
  },

通過上面這段代碼我們調用的時候傳節點的id會返回一個數組,數組包含它所在路徑上的對象,這樣我們就可以通過循環遍歷這個數組通過toggleRowSelection反法來實現頁面狀態樣式的改變。

二、反向取消

反向取消正好和選中相反
在點擊子節點取消的時候我們需要判斷同級的節點是不是都取消瞭,如果都取消瞭需要把這個節點的父節點改為取消狀態,之後再查其父節點同級是否都是取消狀態,如果還有取消狀態,同理跟剛才方式一樣接著向其上級節點查找直到不滿足條件為止,跳出循環。

簡單的來個示意圖

在點擊4節點時,會查看同級節點5和6是否是取消狀態,如果都是取消狀態,查他們的上一級2,把2改為false,在查2的同級3是否是取消如果是取消在查1
如果同級有選中狀態會直接跳出循環不進行下一步操作

下面是取消選中代碼

還是用Tree的代碼,把獲取的數組reverse()進行瞭翻轉
第一次循環從點擊那個節點網上查找
這裡使用for循環如果不滿足直接終止後面循環

三、全選

這裡我感覺寫的比較囉嗦,
全選時候我會先通過數據中isChecked來遞歸判斷是否有沒有選中的
如果有沒有選中會遞歸執行把所有數據中的isChecked變為true,如果都選中瞭,會遞歸修改為false,

下面是全選的所有代碼

  /**
   * @describe 全選
   */
  selectAll(selection) {
   console.log(selection);
   let isAllCheck = this.selectAllRecursion(this.tableData);
   // 是否有aa為false代表是有沒選中
   this.checkoutAll(this.tableData, !isAllCheck);
  },
  /**
   * @describe 遞歸判斷isChecked是否都是true,false代表是有沒選中
   */
  selectAllRecursion(arr) {
   let isCheck = true;
   function isRecursion(arr) {
    arr.forEach((item) => {
     if (!item.isChecked) {
      isCheck = false;
      if (item.children) {
       isRecursion(item.children);
      }
     }
    });
   }
   isRecursion(arr);
   return isCheck;
  },
  /**
   * @describe 把所有的夠改為true或者false
   */
  checkoutAll(arr, boole) {
   var _this = this;
   function allCheck(arr, boole) {
    arr.forEach((item) => {
     item.isChecked = boole;
     _this.$refs.multipleTable.toggleRowSelection(item, boole);
     if (item.children) {
      allCheck(item.children, boole);
     }
    });
   }
   allCheck(arr, boole);
  },

END:

基本代碼就以上這些,不包含表格分頁功能

到此這篇關於基於ElementUI中Table嵌套實現多選的示例代碼的文章就介紹到這瞭,更多相關ElementUI Table嵌套多選內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: