Element UI 表格點擊選中行/取消選中 快捷多選 以及快捷連續多選,高亮選中行

ElementUI table自帶的有一個highlight-current-row的屬性,可是隻能單選。因此要實現點擊行選中以及多選得本身實現.javascript

目標:單擊選中/取消, 按ctrl鍵點擊實現多選 ,按shift/alt鍵實現連續多選。css

實現效果

1. 監聽row-click事件,實現選中

<el-table ref="multipleTable" :data="tableData" style="width: 100%" @selection-change="handleSelectionChange" @row-click="rowClick" :row-style="rowStyle" :row-class-name="rowClassName">
            .....
            .....
</el-table>
複製代碼
rowClick(row, column, event) {

   let refsElTable = this.$refs.multipleTable; // 獲取表格對象
   refsElTable.toggleRowSelection(row); // 調用選中行方法
}
複製代碼

2. 實現選中取消,以及單個選中

上面已經實現點擊選中,可是會點擊一行選中一行,因此要使用clearSelection先清空以前選擇的行,而後進行選擇,取消選擇首先要肯定當前點擊的行是否被已被選中,因此先監聽selection-change事件保存已選中行(或者使用$refs獲取內部保存的已選擇行),以及使用row-style給每一行添加惟一標識。html

rowClick(row, column, event) {
       let refsElTable = this.$refs.multipleTable; // 獲取表格對象
       let findRow = this.selectionRow.find(c => c.rowIndex == row.rowIndex);
       if (findRow ) {
           refsElTable.toggleRowSelection(row, false);
            return;
       }
       refsElTable.clearSelection();
       refsElTable.toggleRowSelection(row); // 調用選中行方法
},

rowStyle({row,rowIndex}) {
         Object.defineProperty(row, 'rowIndex', { //給每一行添加不可枚舉屬性rowIndex來標識當前行
         value: rowIndex, 
         writable: true,
         enumerable: false
       })
 },

handleSelectionChange(rows) {
      this.selectionRow = rows //保存已選擇行
  },

複製代碼

3. 按住ctrl實現多選

首先要監聽keydown事件,以及keyup事件,java

methods: {
    rowClick(row, column, event) {
       let refsElTable = this.$refs.multipleTable; // 獲取表格對象
         if (this.CtrlDown) {
              refsElTable.toggleRowSelection(row); // ctrl多選 若是點擊兩次一樣會取消選中
              return;
       }
       let findRow = this.selectionRow.find(c => c.rowIndex == row.rowIndex);
       if (findRow ) {
           refsElTable.toggleRowSelection(row, false);
            return;
       }

       refsElTable.clearSelection();
       refsElTable.toggleRowSelection(row); // 調用選中行方法
    },


    keyDown(event) {
                let key = event.keyCode;
                if (key == 17) this.CtrlDown = true;
            },


    keyUp(event) {
                let key = event.keyCode;
                if (key == 17) this.CtrlDown = false;
        },
},
mounted() {
    addEventListener("keydown", this.keyDown, false);
    addEventListener("keyup", this.keyUp, false);
 },
beforeDestroy() { //解綁
    removeEventListener("keydown", this.keyDown);
    removeEventListener("keyup", this.keyUp);
}
複製代碼

4. shift/alt鍵實現連續多選

這一步要經過rowIndex判斷已選擇的行中最上面和最下面的是哪行,再對比按住shift/alt點擊的當前行獲得新的最上面和最下面的行,把這兩行中間的行進行循環選中。element-ui

computed: { //實時獲得最上行和最下行
    bottomSelectionRow() {
          if (this.selectionRow.length == 0) return null;
            return this.selectionRow.reduce((start, end) => {
                  return start.rowIndex > end.rowIndex ? start : end;
              });
        },
    topSelectionRow() {
           if (this.selectionRow.length == 0) return null;
              return this.selectionRow.reduce((start, end) => {
                  return start.rowIndex < end.rowIndex ? start : end;
              });
          }
   },

methods: {
   rowClick(row, column, event) {
       let refsElTable = this.$refs.multipleTable; // 獲取表格對象
         if (this.CtrlDown) {
              refsElTable.toggleRowSelection(row); // ctrl多選 若是點擊兩次一樣會取消選中
              return;
         }
       
       if ( this.shiftOrAltDown && this.selectionRow.length > 0) { 
                    let topAndBottom = getTopAndBottom(  row, this.bottomSelectionRow, this.topSelectionRow );
                    refsElTable.clearSelection(); //先清空 否則會致使在這兩行中間以外的行狀態不變
                    for (let index = topAndBottom.top; index <= topAndBottom.bottom; index++) { //選中兩行之間的全部行
                        refsElTable.toggleRowSelection(this.tableData[index], true);
                    }
         } else {
              let findRow = this.selectionRow.find(c => c.rowIndex == row.rowIndex); //找出當前選中行
               //若是隻有一行且點擊的也是這一行則取消選擇 不然清空再選中當前點擊行
               if (findRow&& this.selectionRow.length === 1 ) { 
                  refsElTable.toggleRowSelection(row, false);
                  return;
                 }
                 refsElTable.clearSelection();
                 refsElTable.toggleRowSelection(row); 
        }
    },

    rowStyle({row,rowIndex}) {
         Object.defineProperty(row, 'rowIndex', { //給每一行添加不可枚舉屬性rowIndex來標識當前行
         value: rowIndex, 
         writable: true,
         enumerable: false
       })
   },

    keyDown(event) {
                let key = event.keyCode;
                if (key == 17) this.CtrlDown = true;
                if (key == 16 || key == 18) this.shiftOrAltDown = true;
            },


    keyUp(event) {
                let key = event.keyCode;
                if (key == 17) this.CtrlDown = false;
                if (key == 16 || key == 18) this.shiftOrAltDown = false;
        },
},

mounted() {
    addEventListener("keydown", this.keyDown, false);
    addEventListener("keyup", this.keyUp, false);
 },

beforeDestroy() { //解綁
    removeEventListener("keydown", this.keyDown);
    removeEventListener("keyup", this.keyUp);
}

/**獲取最新最上最下行 */
function getTopAndBottom(row, bottom, top) {
        let n = row.rowIndex,
            mx = bottom.rowIndex,
            mi = top.rowIndex;
        if (n > mx) {
            return {
                top: mi,
                bottom: n
            };
        } else if (n < mx && n > mi) {
            return {
                top: mi,
                bottom: n
            };
        } else if (n < mi) {
            return {
                top: n,
                bottom: mx
            };
        } else if (n == mi || n == mx) {
            return {
                top: mi,
                bottom: mx
            };
        }
    };
複製代碼

5. 實現選中高亮

element-ui自己的單選高亮實現方式同樣,都是給選中行加上current-row這個class類,因此要使用row-class-name這個屬性(其實給每一行添加rowIndex也能夠用這個屬性),判斷方式也是經過判斷rowIndex對比bash

rowClassName({ row,  rowIndex }) {
          let rowName = "",
          findRow = this.selectionRow.find(c => c.rowIndex === row.rowIndex);
         if (findRow) {
           rowName = "current-row "; // elementUI 默認高亮行的class類 不用再樣式了^-^,也可經過css覆蓋改變背景顏色
      }
    return rowName; //也能夠再加上其餘類名 若是有需求的話
 },
複製代碼

Demo及代碼

codepen.io/lozvoe/pen/…ui

相關文章
相關標籤/搜索