前言
最近一直在跟表格裏的多選框做鬥爭,一開始覺得el-table本身的多選框不滿足我的需求,想要自定義el-checkbox來實現,結果發現很多坑,還沒解決(主要是數據綁定不同步更新的問題),感覺蠻花時間的,又回頭看看el-table有沒有方法能完善一下,結果成功了,雖然具體實現過程還是很。。。低級,希望可以借鑑這個尋找更好的解決方案,故此記錄
頁面元素:單選框、輸入框、帶多選框的表格
需求
針對頁面元素說明功能需求如下
- 表格
- 帶多選框
- 多選框帶條件性渲染,滿足某條件,多選框不顯示
- 多選框默認全選中
- 單選框
- 根據單選框的切換控制表格多選框是否禁用
- 輸入框
- 顯示多選框選中的數量
- 手動輸入的數字不能超過表格可選數據的總數量
- 手動輸入數字,動態按順序勾選多選框指定數量的數據
實現
el-table 本身就有多選框的功能
故只要加上<el-table-column type="selection"/>
就可以爲表格加上多選框
以下爲我的表格代碼
<el-table ref="dataTable"
:data="goodsList"
highlight-current-row
stripe
:fit="true"
type="index"
:cell-class-name="isRender"
@selection-change="handleGoodsChange">
<el-table-column type="selection"
width="50"
:selectable="checkSelectable" />
<el-table-column prop="name"
label="商品名稱"
sortable />
<el-table-column prop="code"
label="商品編碼"
sortable />
<el-table-column prop="unitprice"
sortable
label="單價" />
<el-table-column prop="num"
label="數量"
sortable />
<el-table-column prop="unit"
label="單位"
sortable />
<el-table-column prop="price"
sortable
label="金額" />
</el-table>
由此帶多選框表格有了
控制多選框是否渲染
使用動態class爲滿足條件的行添加display:none
樣式隱藏多選框
:cell-class-name="isRender" //爲表格的每一行添加class
/**
* 條件判斷,添加樣式
* @param row
* @returns classname
*/
isRender (row) {
if (row.row.status === '1') {
return 'disabled-column'
}
}
<style>
/* 隱藏多選框 */
.disabled-column .el-checkbox__input {
display: none;
}
</style>
默認多選框全選
使用toggleAllSelection()
切換所有行的選中狀態,剛初始化頁面的時候即爲全選
mounted () {
this.$refs.dataTable.toggleAllSelection()
},
單選框和輸入框的頁面元素代碼如下
<div>
<div style="float: left;">
<el-row>
<el-radio v-model="selection"
label="1"
@change="handleSelectionChange">
<template>
勾選商品/勾選前
<el-input v-model="selectedSize"
class="el-input--mini"
max="goodsList.length"
@input="limitMax()" />
<el-button type="primary"
size="small"
:disabled="selection==='2'"
@click="confirmSelect">確認勾選</el-button>
</template>
</el-radio>
</el-row>
<el-row style="float: left;">
<el-radio v-model="selection"
label="2"
@change="handleSelectionChange">最大限額自動拆分</el-radio>
</el-row>
</div>
單選框切換,多選框禁用
需要分爲兩個步驟
- 首先多選框全部選中
對錶格數據進行遍歷,調用toggleRowSelection(row,true)
切換行的選中狀態爲true
,並且排除不可選的行數據
/**
* 條件判斷,多選框全選
*
*/
handleSelectionChange () {
if (this.selection !== '1') {
for (let i = 0; i < this.goodsList.length; i++) {
if (this.goodsList[i].status !== '1') {
this.$refs.dataTable.toggleRowSelection(this.goodsList[i], true)
}
}
}
},
- 多選框全部禁用
多選框使用selectable
決定這一行是否可以勾選
注意:不顯示多選框的行也要禁用,這樣在使用toggleAllSelection()
不會選中這些行
:selectable="checkSelectable"
/**
* 條件判斷,當前行多選框是否禁用
* @param 列表數據
* @returns true/不禁用 false/禁用
*/
checkSelectable (row) {
if (row.status === '1') { //禁用不可選行
return false
}
if (this.selection === '1') { //判斷單選框值
return true
} else {
return false
}
},
輸入框顯示錶格選中的數量
watch: {
/**
* 監控表格選中的數據,更新輸入框顯示的數值
*
*/
selectedGoodsList: {
handler (newval, old) {
this.selectedSize = newval.length
}
}
}
輸入框限制輸入數值的大小
el-input有max屬性,但是有bug,故添加了方法自己判斷
<el-input v-model="selectedSize"
class="el-input--mini"
max="goodsList.length" //木有用
@input="limitMax()" />
/**
* 限制輸入的最大值
*
*/
limitMax () {
const maxSize = this.goodsList.length - this.disablegoodlist.length
if (this.selectedSize > maxSize) {
this.selectedSize = maxSize
}
}
手動勾選表格指定數量的數據
大概思路如下:
-使用clearSelection()
清空表格勾選狀態,
-遍歷表格數據,如果不是不可選數據,則動態選中,如果是不可選的數據,遍歷條件+1,直到循環結束
/**
* 根據輸入框的值動態勾選多選框
*
*/
confirmSelect () {
this.$refs.dataTable.clearSelection()
let count = this.selectedSize
for (let i = 0; i < count; i++) {
if (this.goodsList[i].status !== '1') {
this.$refs.dataTable.toggleRowSelection(this.goodsList[i], true)
} else {
count++
}
}
}
頁面展示