Element-UI 实战系列:Table+Pagination 组件实现已选和全选功能

用户头像
brave heart
关注
发布于: 2020 年 05 月 31 日
Element-UI实战系列:Table+Pagination组件实现已选和全选功能

前言

现在开发的都是Vue项目,所以也就接触到了Element-UI库,在使用Table+Pagination组件的过程中,实现分页多选时,遇到了难题,比如在第一页勾选了Table列表上的多条数据,然后切换到第二页,再切回第一页,就会发现勾选的状态消失了,我们需要的效果当然是,切回第一页时,Table列表上的已勾选的状态还是存在的,本文就是将实现过程记录一下。

效果图

实现过程

这个需求,如果只是已选功能的话,其实很简单,只要把选择的用户,存放到一个新的数组里即可,代码如下所示:

<span>{{`已选 ${selectData.length} 用户`}}</span>
......
<el-table ref="multipleTable"
class="table"
:data="tableData"
@selection-change="handleSelectionChange"
border>
......
</el-table>
......
handleSelectionChange (value) {
this.selectData = value
}



selection-change事件是Table组件支持的返回已勾选用户的数组,那么直接使用this.selectData = value,就可以获取得到当前已选用户的数据了,但是在分页切换后,并不能保留之前在该页勾选的状态,因为这个需求是通过分页加载实现的,其意思是,一开始这个Table列表所展示的50条用户数据不是一下子直接从数据库全部请求回来的,而是每次只请求10条,分页切换之后,再请求回来10条重新赋值到Table列表上,这样tableData的数据就是一直被清空并重新赋值,如以下代码所示:

created () {
this.getTableData()
},
methods: {
getTableData () {
this.tableData = []
for (let index = 0; index < 10; index++) {
this.tableData.push({
index: (this.currentPage - 1) * this.pageSize + index + 1,
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
})
}
}
}

这样就会有一个问题,如果在第一页什么都没勾选,那么切换到第二页的时候,是不会触发selection-change时间的,但如果第一页有勾选了用户,那么切换至第二页,就会触发该事件,并且其值为空数组,因为selection-change事件触发条件是,当选择项发生变化,为了解决这个问题,就想到了将每一页已选的用户分别存放到一个数组里,然后该数组又放到selectData对应的下标位置,代码如下所示:

<span>{{`已选 ${selectedLampsNum} 用户`}}</span>
......
handleSelectionChange (value) {
if (value.length !== 0) {
this.selectedLampsNum = 0
this.selectData[this.currentPage - 1] = value
this.selectData.forEach(item => {
this.selectedLampsNum = this.selectedLampsNum + item.length
})
}
}

以上代码之所以需要判断value.length !== 0是因为,为了防止切换时,将之前已经勾选的用户数据清空,但是这里会造成一个问题,那就是清空该页的操作,也是会出现val.length===0的情况,所以这里还要想下怎么处理这个情况,怎么区分分页切换后已选用户数据为空,是页面数据初始化触发的,还是点击清空勾选框触发的? 

然后,我就去看下Element-UI上面Table组件,看下有没有什么好的办法,然后还真被我找到了,我将@selection-change改为@select@select-all两个事件,完美解决遇到的这个难题,代码如下所示:

<el-table ref="multipleTable"
class="table"
:data="tableData"
@select="handleSelectionChange"
@select-all="handleSelectionChange"
border>
</el-table>
......
handleSelectionChange (value) {
this.selectedLampsNum = 0
this.selectData[this.currentPage - 1] = value
this.selectData.forEach(item => {
this.selectedLampsNum = this.selectedLampsNum + item.length
})
}

接下来,就是实现如果在分页切换后,还保留上一页已选的勾选状态,其实就是,在分页数据初始化的时候,判断下之前是否在该页,有过选择的用户,如果有的话,就通过this.$refs.multipleTable.toggleRowSelection(item, true)设置其Checkbox为勾选状态,代码如下所示:

getTableData () {
this.tableData = []
for (let index = 0; index < 10; index++) {
this.tableData.push({
index: (this.currentPage - 1) * this.pageSize + index + 1,
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
})
}
// 设置已勾选状态
if (this.selectData[this.currentPage - 1] !== undefined) {
var selectUserList = this.selectData[this.currentPage - 1]
this.$nextTick(() => {
this.tableData.forEach(item => {
selectUserList.forEach(user => {
if (item.index === user.index) {
this.$refs.multipleTable.toggleRowSelection(item, true)
}
})
})
})
}
}

至于全选功能,其实和已选功能一样,核心都在这行代码this.$refs.multipleTable.toggleRowSelection(item, true),代码如下所示:

if (this.isSelectAll) {
this.$nextTick(() => {
this.tableData.forEach(item => {
this.$refs.multipleTable.toggleRowSelection(item, true)
})
})
} else {
this.$refs.multipleTable.clearSelection()
}

写在最后

我其实也在怀疑写这个东西的意义何在,有时候会想,未免小题大做了,但是在当时确实给自己带来了很大的困扰,做我自己就好了,希望自己可以探索得更为深入,而不是浮于表面。



示例代码:https://github.com/BRAVE2HEART/infoq-vue-example



发布于: 2020 年 05 月 31 日 阅读数: 97
用户头像

brave heart

关注

唯一不变的是变化本身。 2018.04.17 加入

🗡 她只唱只想这首止战之殇。

评论

发布
暂无评论
Element-UI实战系列:Table+Pagination组件实现已选和全选功能