由于产品的需求,我们在使用element-ui 的table时,可能会用到带复选框的table,但是,这个复选框在我们使用分页切换下一页时,上一页选中没有提交的选项是没有保存的,因为每一页的数据都是直接从接口获取的,基于这种情况,为了记住我们每一页的选项,我这里分享一种方法,于是便写下了这篇文章。
另外还针对这个问题出了第二套方案,我觉得第二套方案更好,小伙伴们如果想节约时间的话可以直接移步第二套方案噢
文章目录
- 1、插话
- 2、分析
- 3、方案
- 4、实现
- 5、效果
- 6、总结
1、插话
有同学可能会说:“我在切换页码时对该页的选项进行保存也可以呀”
是的,这种方法确实可以,但是呢,如果页数过多,我们每一页都有要修改选项时,频繁请求接口,就会对服务器造成一种负担,这明显违背了性能优化的思想。
除此以外,还有一个很重要的原因,那就是,产品说:“我不想每一页都点保存,我要每一页都操作结束之后,点一次保存,提交所有被操作的选项”
2、分析
我们都知道造成这种table选择状态没有保存的原因是因为数据刷新与重新渲染,刷新是接口数据返回了新的数据,渲染是根据发生变化的数据渲染,知道了问题所在,我们开始制定实现方法。
3、方案
1、初始化一个changList[]
2、将接口返回的列表数据进行处理,选中状态的添加进changList中
3、渲染数据,根据changList中的项来判断多选框的状态
4、多选框状态改变时将改变的项添加到changList中
5、切换页面的时候则重复2-4的步骤
导图如下:
4、实现
script代码
//定义全局变量
const changeList = []
data() {
return {
/** 组件自动处理得到的此时选中的选项 */
multipleSelection: [],
}
}
//利用计算属性计算changList
computed: {
changeList() {
const { multipleSelection } = this
//比对组件得到的选中数据与changList
//changList中不存在则push进去
multipleSelection.map((item) => {
const { itemId } = item
const exit = changeList.findIndex(item => item.itemId === itemId) >= 0
if (!exit) {
changeList.push({ itemId, state: true })
}
})
return changeList
}
},
methods: {
fetchList() {
/**
* 此处请求接口获取到后台返回的数据列表list
*/
//对数据进行渲染
this.$nextTick(() => {
this.list.forEach(item => {
const { itemId } = item
const exit = changeList.findIndex(items => items.itemId === itemId)
if (exit >= 0) {
this.$refs.multipleTable.toggleRowSelection(item, changeList[exit].state)
} else {
this.$refs.multipleTable.toggleRowSelection(item, item.state)
}
})
})
}
}
methods: {
//此处照搬文档
handleSelectionChange(val, index) {
this.multipleSelection = val
},
//行选则时的处理逻辑
handleRowClick(val) {
const { multipleSelection } = this
const { itemId } = val
const state = multipleSelection.findIndex(item => item.itemId === itemId) >= 0
this.checkChooseState(itemId)
this.$refs.multipleTable.toggleRowSelection(val, !state)
},
//此处关键,由于直接点击checkbox无法直接获取当前行的数据
//于是我禁用checkbox选择,采用点击checkbox所在行来获取当前行数据
checkSelectable() {
return false
},
//此处关键 判断变化的选项是否存在于changList中
//存在则修改状态为false
//无需在这里添加,我们有计算属性帮我们处理
checkChooseState(id) {
changeList.map((item) => {
const { itemId } = item
if (id === itemId) {
item.state = false
}
})
}
}
template代码
<template>
<el-table
ref="multipleTable"
:chang="changList"
:data="list"
tooltip-effect="dark"
style="width: 100%"
@selection-change="handleSelectionChange"
@row-click="handleRowClick"
>
<el-table-column
type="selection"
width="55"
:selectable="checkSelectable"
/>
<el-table-column
prop="liveCompanyName"
label="公司名"
/>
</el-table>
</template>
style代码
注释:由于禁用checkbox,它的样式就会变灰,中间的勾也会变灰,所以恢复它的样式,需要添加额外的控制样式的代码
<style lang="less" scoped>
/deep/ .el-table--enable-row-transition .el-table__body td {
-webkit-transition: background-color .25s ease;
transition: background-color .25s ease;
cursor: pointer;
}
/deep/ .el-checkbox__input.is-disabled.is-checked .el-checkbox__inner:after{
border-color: #fff;
}
/deep/ .el-checkbox__input.is-disabled.is-checked .el-checkbox__inner{
background-color: #409eff;
}
</style>
5、效果
首次打开table,changList长度由0->2,因为有两个已选项
现在我们选中最后一项,changList长度由2->3
接下来我们切换到第二页,有7个默认选中项,changList长度由3->10
这时我们再新增一个选项,changList长度变成了11
切回第一页长度不变还是11
我们再新增一项,changList长度变成12
我们取消一项已选的,现在changList长度还是12,但是取消的那一项的标志变成了false
最后,我们将changList传给后端即可,里面包含默认项以及用户操作的变化项
6、总结
本来实现的效果是想通过视频的形式分享出来的,可是想着对视频中的数据打码太麻烦就换成了图片,虽然很low,但是也尽量让大家看到效果