分享基于el-table的翻页回显选中实现方案
需求场景描述
一个表格,具备可选行的那种,要求在换页的时候,上一页选中的选项状态保留,切换多个页码选中信息,这些选中项要保留,并在表格顶部显示选中的总数。本案例是基于el-table实现的。注意每个页都可以支持全选,但是这个全选仅仅是当前页全选,这个状态也要保持。
实现方案思路分析
1.设置数组变量 multipleSelection 保存选中信息,数组变量 list 为原始每页的数据信息。监听表格的单击选中事件,利用el-table的事件@select实现,及时同步当前页选中信息到 multipleSelection。
应注意判断当前选中信息是否已经存在 multipleSelection,避免重复数据。
关于当前单选操作是取消选中操作还是选中操作,我们可以巧妙的利用当前操作的row在不在multipleSelection中,在则是取消选中操作,不在则是选中操作。
处理单选功能的函数如下:
handleSelect (selection, row) {
// 同步选中的数据到 multipleSelection
const index = this.multipleSelection.findIndex(e => e.id === row.id)
// 当 multipleSelection 有 row,则说明本次操作是取消勾选,进而删除
if (index > -1) {
this.multipleSelection.splice(index, 1)
} else {
this.multipleSelection.push(row)
}
},
2.全选功能则利用el-table的监听全选事件@select-all,同步当前页选中信息到 multipleSelection。同步逻辑是利用map函数,将选中的信息从 list 中过滤到 multipleSelection。过滤规则是,此时全选,那么应当是当前页全部都应当加入到选中数组 multipleSelection 中。
注意,不重复添加。保证不重复添加的逻辑可以是,遍历list,结合 multipleSelection.findIndex()确定该行信息是否已经在multipleSelection中,存在则不添加,不存在则添加。
此外,可利用handleSelectAll的回调值,selection.length来判断当前操作是全选还是取消全选。selection.length大于0表示是全选操作,否则是取消全选操作。
处理全选功能的函数如下:
handleSelectAll (selection) {
this.list.map(row => {
const index = this.multipleSelection.findIndex(e => e.id === row.id)
// 全选,将选项加入 multipleSelection
if (selection.length && index === -1) {
this.multipleSelection.push(row)
}
// 取消全选,将选项从 multipleSelection 中移除
if (!selection.length && index > -1) {
this.multipleSelection.splice(index, 1)
}
})
},
3.翻页回显已选中的信息。翻页的时候必然是从新请求接口了,此时更新后的当前页数据list,在list中通过map寻找multipleSelection中的行数据,属于两个数组的交集的数据则是已被选中的信息,我们需要荣国el-table的 toggleRowSelection方法,设置相应的行数据的选中状态,来到达数据驱动视图回显选中状态的目的。
注意,我们应当在每次翻页更新数据时,调用回显函数,进行回显。处理回显逻辑的函数如下:
toggleSelection (selection, list) {
if (!selection.length || !list.length) return
list.map(item => {
const index = selection.findIndex(e => {
return e.id === item.id
})
if (index > -1) {
this.$nextTick(() => {
this.$refs.multipleTable.toggleRowSelection(item)
})
}
})
},
主要关键代码集合
1.html代码
<div>您选中 {{ total }} 项</div>
<el-table @select="handleSelect"
@select-all="handleSelectAll"
:data="list">
</el-table>
2.js代码
// 全选按钮同步选中信息
handleSelectAll (selection) {
this.list.map(row => {
const index = this.multipleSelection.findIndex(e => e.id === row.id)
// 全选,将选项加入 multipleSelection
if (selection.length && index === -1) {
this.multipleSelection.push(row)
}
// 取消全选,将选项从 multipleSelection 中移除
if (!selection.length && index > -1) {
this.multipleSelection.splice(index, 1)
}
})
},
// 单行选中按钮同步选中信息
handleSelect (selection, row) {
// 同步选中的数据到 multipleSelection
const index = this.multipleSelection.findIndex(e => e.id === row.id)
// 当 multipleSelection 有 row,则说明本次操作是取消勾选,进而删除
if (index > -1) {
this.multipleSelection.splice(index, 1)
} else {
this.multipleSelection.push(row)
}
},
// 选中信息回显到页面中
toggleSelection (selection, list) {
if (!selection.length || !list.length) return
list.map(item => {
const index = selection.findIndex(e => {
return e.id === item.id
})
if (index > -1) {
this.$nextTick(() => {
this.$refs.multipleTable.toggleRowSelection(item)
})
}
})
},
// 查询数据
search () {
const params = {}
this.$api.getResearchList(params).then(res => {
this.list = res.data.rows || []
this.total = res.data.total || 0
this.toggleSelection(this.multipleSelection, this.list)
})
},