使用e-table分页多选,回显
很多次碰到要做表格多选加分页的,在这里记录一下
主要需求:
-
表格要求可以多选,可以分页
-
选择数据之后,切换分页数据仍存在,再次切换回去,能正常回显
功能展示:
左侧为table表格,右侧是已选择的展示
首页选择人员
第二页选择人员,第一页选择的数据仍在
切换回第一页,正常回显数据
选择的数据传递到界面
再次打开弹窗,数据仍正常回显
具体实现:
-
首先,给表格添加分页与选择功能
<!-- table表头设置row-key,需要唯一标识 --> <el-table :row-key="(row) => { return row.userId }" ></el-table> <!-- 添加多选,设置type="selection" --> <el-table-column type="selection" width="55" :reserve-selection="true"> </el-table-column> <!-- 添加分页组件 --> <el-pagination :page-sizes="[10, 50, 100]" :currentpage="Number(form.pageNum)" :page-size="Number(form.pageSize)" :total="Number(form.total)" layout="prev,pager,next,sizes,jumper" @size-change="onSizeChange" @current-change="onCurrentChange" />
表格做了分页功能,切页会请求后台,之前选择的的数据的勾选状态就不存在了,element提供了reserve-selection可以保存数据更新前选中的值,这个属性需要搭配 row-key 指定一个唯一标识。所以要在表格多选列设置
reserve-selection='true'
-
当设置了row-key和reserve-selection基本就成了
-
使用selection-change函数记录勾选的值
selection-change:当选项发生变化时会触发该函数
<el-table @selection-change="handleSelectionChange" ></el-table>
//selectList为勾选的值组成的数组
handleSelectionChange(arr) {
this.selectList = arr
}
-
回显数据:
通过element提供的内置函数
toggleRowSelection()
来实现我们的数据回显
//给table设置ref属性
<el-table ref="multipleTable" :data="tableData"></el-table>
//数据回显
toggleSelection(rows) {
//使用$nextTick,保证dom已经更新
this.$nextTick(() => {
setTimeout(() => {
//保证有值再进行比对,避免报错
if (rows && this.tableData.length != 0) {
//遍历table表格数据与要回显的数组比对,匹配成功的设置为选中状态
this.tableData.forEach((row) => {
rows.forEach((item) => {
if (row.userId == item.userId) {
//判断唯一标识,若是id一样,则设置该行选中状态为true
this.$refs.multipleTable.toggleRowSelection(row, true)
}
})
})
} else {
this.$refs.multipleTable.clearSelection();
}
}, 0);
});
}
注意:因为我们这里做了分页,分页时会重新请求后台,所以每次请求后要调用一次toggleSelection函数来回显当前页的数据
- 至此,我们表格的分页多选回显功能就做的差不多了
完整代码:
仅供参考
<el-table :data="tableData" @row-click="rowClick" @selection-change="handleSelectionChange" ref="multipleTable" stripe border style="width: 100%" :row-key="(row) => { return row.userId }" height="calc(100% - 48px)">
<el-table-column type="selection" width="55" :reserve-selection="true">
</el-table-column>
<el-table-column type="index" label="序号" align="center" width="50px">
<template slot-scope="scope">
{{ (form.pageNum - 1) * form.pageSize + scope.$index + 1 }}
</template>
</el-table-column>
<el-table-column align="center" label="姓名" prop="userName" />
</el-table>
<el-pagination :page-sizes="[50, 100, 1000, 2000]" :current-page="Number(form.pageNum)" :page-size="Number(form.pageSize)" :total="Number(form.total)" layout="prev,pager,next,sizes,jumper" @size-change="onSizeChange" @current-change="onCurrentChange" />
<script>
export default {
data() {
return {
tableData: [],//表格table
form: {
pageNum: 1,
pageSize: 50,
total: 0,
},
selectList: [],//选中的list
};
},
mounted() {
this.getList()
},
methods: {
// 获取列表
async getList() {
let { rows, total } = await user_list(this.form);
this.tableData = rows;
this.form.total = total
this.toggleSelection(this.selectList)
},
// 选择人员发生变化时
handleSelectionChange(arr) {
this.selectList = arr
},
// 数据回显
toggleSelection(rows) {
this.$nextTick(() => {
setTimeout(() => {
if (rows && this.tableData.length != 0) {
this.tableData.forEach((row) => {
rows.forEach((item) => {
if (row.userId == item.userId) { this.$refs.multipleTable.toggleRowSelection(row, true)
}
})
})
} else {
this.$refs.multipleTable.clearSelection();
}
}, 0);
});
},
//分页
onSizeChange(size) {
this.form.pageSize = size
this.getList();
},
onCurrentChange(current) {
this.form.pageNum = current
this.getList();
},
},
}
</script>
补充:
做好之后,发现是存在一些bug的
-
初次数据回显时,会触发
handleSelectionChange
函数,导致传入的list被覆盖修改,切换分页时后面的数据已经不存在了解决方案:data中添加一个flag变量来判断编辑回显
falg:false, handleSelectionChange(arr) { if (this.falg) return this.selectList = arr }, toggleSelection(rows) { this.$nextTick(() => { setTimeout(() => { this.rowSelectFlag = true ... this.rowSelectFlag = false }, 0); }); },
-
回显数据后进行修改数据,只会保存当前页的数据,其他分页的数据被刷掉
- 本菜鸡还没找到解决方法,如果大佬知道麻烦评论告知一下,万分感谢
如果还有什么其他的问题,欢迎大佬们评论指教,小弟拜谢了