el-table的选取通常是在事件中监听selection-change
事件,将选中的行赋给绑定的数组。示例代码如下:
<el-table
ref="multipleTable"
border
stripe
max-height="2000"
header-align="center"
:data="tableData"
:header-cell-style="{ background: '#f0f0f0' }"
style="width: 100%"
@selection-change="handleSelectionChange"
>
<el-table-column type="index" width="55" />
<el-table-column prop="column1" label="column1" />
<el-table-column prop="column2" label="column2" />
</el-table>
export default {
data(){
return{
items:[]
}
}
}
methods:{
handleSelectionChange(val) {
this.items= val;
},
}
然而在实际表格数据选取中,由于表格数据通常是带有分页的,在选取了当前页后,如果还要去选择其他页面中的数据,就需要将选中的数据推到绑定的数组中。这时selection-change
事件的处理函数就应该改为:
handleSelectionChange(selection){
let rows = selection.map(item => item)
if(rows.length >0){
rows.forEach(row=>{
if(!this.items.some(r=>r.id == row.id)){
this.items.push(row)
}
})
}
},
如果是在当前页面能正确的获取到所选的多行数据。 其他页面如果要使用当前页面中的数据,可以将该页面作为其他页面的组件,将数组传值到父页面。这里,就需要先在父页面中引用该组件。然后通过this.$emit方法将数值传输到父页面数值或者方法中。代码如下:
<items-list ref="itemsList" :category="params.category"
:type="params.type" @selected="selected" @closeDialog="closeDialog"></items-list>
import ItemsList from './itemsList'
export default {
name: 'ParentItem',
components: { ItemsList },
data(){
return {
itemList:[]
}
}
}
methods:{
selected(items){
if(Array.isArray(this.itemList) && this.itemList.length >= 0
&& Array.isArray(items) && items.length > 0){
items.forEach(item=>{
if(!this.itemList.some(r=>r.id == item.id)){
this.itemList.push(item)
}
})
}
},
}
子组件页面中的selection-change
事件的处理函数中就需要加上一句 this.$emit('selected',this.items),如下:
handleSelectionChange(selection){
let rows = selection.map(item => item)
if(rows.length >0){
rows.forEach(row=>{
if(!this.checkedRows.some(r=>r.id == row.id)){
this.checkedRows.push(row)
}
})
}
this.$emit('selected',this.items)
},
在对子组件进行勾选操作时,可以通过勾选操作将行加到绑定的数组中来。但有时笔者对已经勾选的行想要取消掉勾选,或者通过使用全选框全部取消选择。这就要求绑定的数组对象既可以推数据进去,也可以按要求删数据。因此,增加对el-table的select和select-all事件的监听。
<el-table
ref="multipleTable"
border
stripe
max-height="2000"
header-align="center"
v-loading="loading"
:data="tableData"
:header-cell-style="{ background: '#f0f0f0' }"
style="width: 100%"
@select="onTableSelect"
@selection-change="handleSelectionChange"
@select-all="selectAll"
>
methods:{
selectAll(selection) {
if(selection.length == 0){
this.tableData.forEach(item=>{
const index = this.items.findIndex((i) => i.id === item.id)
if(index !== -1){
this.items.splice(index,1)
}
})
}
},
onTableSelect(rows, row) {
let selected = rows.length && rows.indexOf(row) !== -1
if(!selected){
this.items.splice(this.items.findIndex((item) => item.id ===
row.id),1)
}
},
}
选择事件和全选事件中,判断是否是取消选择的依据是全选的参数长度为0,选择的2个参数中,rows中不包含row。
这时候,笔者关闭选择组件的页面,旋即又打开重新选择,发现上一次的勾选还在,事实上笔者是希望它们能在重新打开后消失不见。那么就需要在关闭的时候把勾选的行取消选择,同时将绑定的数组清空。
closeDialog(){
this.resetDialog()
this.$emit('closeDialog',false)
},
resetDialog(){
this.items = []
this.$nextTick(()=>{
this.$refs.multipleTable.clearSelection()
})
},
但如果又想之前已经选中的,在分页回到该页的时候依然是选中状态。那又该如何处理呢?代码展示:
// 获取列表
async getList() {
this.formInline.type = this.type
this.formInline.category = this.category
this.loading = true
let { data } = await getItemList(this.formInline)
this.total = data.page.total;
this.tableData = data.page.records;
this.loading = false
this.checkoutDataTimer = setTimeout(() => {
if(Array.isArray(this.items) && this.items.length > 0){
this.items.forEach(item=>{
const row = this.tableData.find((i) => i.id === item.id)
if(row){
this.$refs.multipleTable.toggleRowSelection(row,true)
}
})
}
}, 1000)
},
这里之所以要用setTimeout方法,是因为表格渲染需要时间。如果表格没有渲染完成,勾选的方法就不能执行成功。当然,在页面销毁的时候,释放checkoutDataTimer 定时器是需要的。
beforeDestroy() {
this.items = []
this.$nextTick(()=>{
this.$refs.multipleTable&& this.$refs.multipleTable.clearSelection()
})
this.checkoutDataTimer &&
clearTimeout(this.checkoutDataTimer)
},
destroyed() {
this.items = []
this.$nextTick(()=>{
this.$refs.multipleTable&& this.$refs.multipleTable.clearSelection()
})
this.checkoutDataTimer &&
clearTimeout(this.checkoutDataTimer)
},
零零散散写了一些琐碎的方法,是目前笔者在前端工作中经常碰到的一些基础性问题,希望能为您带来参考和帮助。