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屬性而不賦值,這樣該列就不會新增展開箭頭。
此文章為原創文章,原文地址:https://www.cnblogs.com/eagle1098/p/13982996.html