Element UI 表格點(diǎn)擊選中行/取消選中 快捷多選 以及快捷連續(xù)多選,高亮選中行

ElementUI table自帶的有一個(gè)highlight-current-row的屬性况木,但是只能單選垒拢。所以要實(shí)現(xiàn)點(diǎn)擊行選中以及多選得自己實(shí)現(xiàn).
目標(biāo):單擊選中/取消旬迹, 按ctrl鍵點(diǎn)擊實(shí)現(xiàn)多選 ,按shift/alt鍵實(shí)現(xiàn)連續(xù)多選求类。

實(shí)現(xiàn)效果

GIF.gif

1. 監(jiān)聽row-click事件奔垦,實(shí)現(xiàn)選中

 <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); // 調(diào)用選中行方法
}

2. 實(shí)現(xiàn)選中取消,以及單個(gè)選中

上面已經(jīng)實(shí)現(xiàn)點(diǎn)擊選中仑嗅,但是會點(diǎn)擊一行選中一行宴倍,所以要使用clearSelection先清空之前選擇的行,然后進(jìn)行選擇仓技,取消選擇首先要確定當(dāng)前點(diǎn)擊的行是否被已被選中鸵贬,所以先監(jiān)聽selection-change事件保存已選中行(或者使用$refs獲取內(nèi)部保存的已選擇行),以及使用row-style給每一行添加唯一標(biāo)識脖捻。

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); // 調(diào)用選中行方法
}阔逼,

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

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

3. 按住ctrl實(shí)現(xiàn)多選

首先要監(jiān)聽keydown事件,以及keyup事件,

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

       refsElTable.clearSelection();
       refsElTable.toggleRowSelection(row); // 調(diào)用選中行方法
    }地沮,


    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鍵實(shí)現(xiàn)連續(xù)多選

這一步要通過rowIndex判斷已選擇的行中最上面和最下面的是哪行,再對比按住shift/alt點(diǎn)擊的當(dāng)前行得到新的最上面和最下面的行摩疑,把這兩行中間的行進(jìn)行循環(huán)選中危融。

computed: { //實(shí)時(shí)得到最上行和最下行
    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多選 如果點(diǎn)擊兩次同樣會取消選中
              return;
         }
       
       if ( this.shiftOrAltDown && this.selectionRow.length > 0) { 
                    let topAndBottom = getTopAndBottom(  row, this.bottomSelectionRow, this.topSelectionRow );
                    refsElTable.clearSelection(); //先清空 不然會導(dǎo)致在這兩行中間之外的行狀態(tài)不變
                    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); //找出當(dāng)前選中行
               //如果只有一行且點(diǎn)擊的也是這一行則取消選擇 否則清空再選中當(dāng)前點(diǎn)擊行
               if (findRow&& this.selectionRow.length === 1 ) { 
                  refsElTable.toggleRowSelection(row, false);
                  return;
                 }
                 refsElTable.clearSelection();
                 refsElTable.toggleRowSelection(row); 
        }
    },

    rowStyle({row,rowIndex}) {
         Object.defineProperty(row, 'rowIndex', { //給每一行添加不可枚舉屬性rowIndex來標(biāo)識當(dāng)前行
         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. 實(shí)現(xiàn)選中高亮

element-ui本身的單選高亮實(shí)現(xiàn)方式一樣吉殃,都是給選中行加上current-row這個(gè)class類,所以要使用row-class-name這個(gè)屬性(其實(shí)給每一行添加rowIndex也可以用這個(gè)屬性)楷怒,判斷方式也是通過判斷rowIndex對比

rowClassName({ row,  rowIndex }) {
          let rowName = "",
          findRow = this.selectionRow.find(c => c.rowIndex === row.rowIndex);
         if (findRow) {
           rowName = "current-row "; // elementUI 默認(rèn)高亮行的class類 不用再樣式了^-^,也可通過css覆蓋改變背景顏色
      }
    return rowName; //也可以再加上其他類名 如果有需求的話
 },

Demo及代碼

https://codepen.io/lozvoe/pen/jgeKME

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蛋勺,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子鸠删,更是在濱河造成了極大的恐慌抱完,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件刃泡,死亡現(xiàn)場離奇詭異巧娱,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)烘贴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進(jìn)店門家卖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人庙楚,你說我怎么就攤上這事上荡。” “怎么了?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵酪捡,是天一觀的道長叁征。 經(jīng)常有香客問我,道長逛薇,這世上最難降的妖魔是什么捺疼? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮永罚,結(jié)果婚禮上啤呼,老公的妹妹穿的比我還像新娘。我一直安慰自己呢袱,他們只是感情好官扣,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著羞福,像睡著了一般惕蹄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上治专,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天卖陵,我揣著相機(jī)與錄音,去河邊找鬼张峰。 笑死泪蔫,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的喘批。 我是一名探鬼主播鸥滨,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼谤祖!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起老速,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤粥喜,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后橘券,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體额湘,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年旁舰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了锋华。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,503評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡箭窜,死狀恐怖毯焕,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤纳猫,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布婆咸,位于F島的核電站,受9級特大地震影響芜辕,放射性物質(zhì)發(fā)生泄漏尚骄。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一侵续、第九天 我趴在偏房一處隱蔽的房頂上張望倔丈。 院中可真熱鬧,春花似錦状蜗、人聲如沸需五。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽警儒。三九已至,卻和暖如春眶根,著一層夾襖步出監(jiān)牢的瞬間蜀铲,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工属百, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留记劝,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓族扰,卻偏偏與公主長得像厌丑,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子渔呵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 返回上次光標(biāo)的位置Ctrl+Alt+ left/right 返回至上次瀏覽的位置 Alt+回車 導(dǎo)入包,自動修正C...
    請叫我四爺閱讀 1,943評論 1 2
  • Eclipse常用快捷鍵 1幾個(gè)最重要的快捷鍵 代碼助手:Ctrl+Space(簡體中文操作系統(tǒng)是Alt+/)快速...
    山不轉(zhuǎn)人自轉(zhuǎn)閱讀 1,458評論 0 10
  • PHPStorm 下載及主題樣式下載 http://www.lanmps.com/html/tools.html風(fēng)...
    手表大大閱讀 2,650評論 0 1
  • 1.輸入psv就會看到一個(gè)psvm的提示怒竿,此時(shí)點(diǎn)擊tab鍵一個(gè)main方法就寫好了帮掉。psvm 也就是public ...
    兜兜又喊阿兵哥閱讀 1,117評論 0 0
  • 珠珠是一只純種的金巴狗趣竣,渾身毛色雪白聪轿,耷拉著耳朵洼滚,眼睛很大良拼,黑眼珠轉(zhuǎn)來轉(zhuǎn)去透著靈氣跷车,咧著大嘴看起來憨態(tài)可...
    螢火蟲之夜閱讀 460評論 0 3