el-talbe中的全選和翻頁記憶功能
場景描述: 使用的是elementui, 一個列表dataList, 列表外有個群發按鈕, 點擊之后, 會在列表的最后一欄動態添加操作, 每行數據后面添加一個checkbox可以選擇, 並且支持翻頁記錄,即第一頁選擇之后, 翻到第二頁, 在回到第一頁, 之前選中的還在.
這個是鏈接: elementui中的el-table elementui中的el-checkbox
前提:
- 列表的數據是分頁獲取的, 每次翻頁都會重新獲取.
- 最后的選擇列是動態生成的, 不是一開始就有的.
- 列表頁在路由中設置過緩存,幾 meta: { keepAlive: true }
踩坑過程:
- el-table本身自帶翻頁緩存功能, 只需添加兩個屬性,即可是實現
// 關鍵代碼
<el-talbe :data="dataList" ref="table" :row-key="(row)=>{return row.id}" @row-click="onRowClick" @selection-change="handleSelectionChange">
<el-table-column type="selectoin" :reserve-selection="true" />
</el-table>
// 在el-table中添加 :row-key 表示row的唯一值
// 在el-table-column 中添加 type="selectoin" :reserve-selection="true"
// @selection-change 返回已選的數據
// this.$ref.table.clearSelection()用於清楚所選
然而,理想很豐滿, 顯示很骨感
因為type="selection" 是動態生成的, 所以上述流程不生效.
-
可以考慮從數據處理方向入手
- 維護一份已選擇的數據表arr,單獨定義選擇事件,
- 選中的時候添加到arr, 刪除的時候,從arr刪除,
- 每次翻頁的時候比較, 比較當前數據(dataList)中有沒有id在已選的arr中也存在的,如果有,則勾選, 沒有,就不勾選.這里dataList和arr都是對象數組, 可能會比較復雜.
-
過程
- 從dataList獲取的時候, 在每個元素上添加一個屬性isChecked: false, 可在獲取數據的方法中操作,或數據返回的接口中操作
- 動態添加一列, 綁定在checked
<el-table-column width="60px" label="操作" v-if="taskFlag"> <template slot-scope="scope"> <el-checkbox v-model="scope.row.checked" @click.prevent.stop.native="handleSelected(scope.row)" :disabled="!scope.row.class_id"></el-checkbox> </template> </el-table-column>
- 在點擊事件中添加方法,處理arr數組的添加和刪除
handleSelected(item) {
if(!item.class_id) return
item.checked = !item.checked
if(item.checked) {
this.selectedId.push(item)
}
if(!item.checked) {
var tempIndex = -1
this.selectedId.forEach((itemData, index) => {
console.log('itemData', itemData)
if(item.id == itemData.id) {
tempIndex = index
}
})
if(tempIndex === -1) {
console.log('沒找到')
return
}
if(tempIndex > -1) {
console.log('刪除')
this.selectedId.splice(tempIndex, 1)
}
}
},
+ 最后在監視頁面的改變,可以watch dataList, 如果翻頁,dataList就會改變, 然后比較dataList 和 arr 里面的數據, 判斷每一行是否需要勾選
watch: {
dataList(val, old){
if(val.length) {
var data_arr = this.selectedId.map(item => {
return item.id
})
val.forEach(item => {
if(data_arr.indexOf(item.id) > -1) {item.checked = true}
})
}
}
},
-
結果 ~~ 又有一個坑
原因: 列表有點擊事件, @row-click, 所以需要防止冒泡, 這里自然想到 .stop,
然而,@change.stop 會報錯, 而官方文檔沒有提供@click方法, 但是原生的checkbox是存在的, 所以使用 @click.stop.native, 但是這個觸發了另一個問題, 該方法會執行2次, 原因是el-checkbox的源碼中, 有嵌套的組件都有@click事件, 此處具體沒有深究, 並且也不能組織冒泡, 頁面還是跳轉了. 查資料后得知,這里要使用.prevent, 阻止默認行為, 這樣就出現了上面哪個 @click.prevent.stop.native寫法. 但是還是出現了新的問題, .prevent之后,會使 :disable失效, 雖然還是有disable的樣式,(hover的時候顯示 cursor: not-allowed) ,但是還是能選中, 需要給個不符合條件的直接return的邏輯. -
除了代碼有點low, 功能是實現了,
-
接下來搞清楚 el-checkbox 中的源碼, 為什么會有這些坑!!!