效果预览
实现思路
- data中定义 selectedList 数组保存选中的数据
- 在页面初次渲染、翻页、切换每页数据数量等每次重新获取表格数据渲染表格时,都根据 selectedList 勾选表格中已经选中的行
- 切换单行勾选状态时,判断是选中还是取消选中,选中则增加选中项,取消选中则移除选中项。
- 切换全选和取消全选时,根据当前页选中行的数据进行更新,若选中行已在 selectedList 中则不再重复添加,否则添加,对于其他非选中行若已在selectedList 中,则从 selectedList 中移除。
技术难点
1. 不能使用 selection-change 的原因
selection-change 的参数为当前页选中的所有行,在每次重新获取数据渲染表格时(如翻页时),参数为一个空数组,会导致历史选中的数据被清空!
即便使用 :reserve-selection="true"
来保留历史选中记录也无法达到预期效果。
2. toggleRowSelection失效的原因解析和解决方案
toggleRowSelection失效通常为以下两种情况:
(1)表格数据发生变化,表格还没渲染完便执行了toggleRowSelection
解决方案 : 在 $nextTick 中执行 toggleRowSelection
// toggleRowSelection 需在$nextTick中使用!
this.$nextTick(() => {
this.$refs.multipleTable.toggleRowSelection(row);
});
(2)toggleRowSelection的第一个参数不是表格源数据
即便数据的值完全一样也会失效,因为数据为引用类型,必须地址一样。
解决方案 :toggleRowSelection的第一个参数通过在表格数据中通过 find() 查找得到。文章来源:https://www.toymoban.com/news/detail-409383.html
this.$nextTick(() => {
this.$refs.multipleTable.toggleRowSelection(
// 此处必须在 tableData 中查找对应的数据,否则 toggleRowSelection 会失效
this.tableData.find((row) => {
return row[this.UID] === item[this.UID];
}),
false
);
});
完整范例代码
<template>
<div class="mainBox">
<h3>已选择:</h3>
<el-tag
:key="item[UID]"
v-for="(item, index) in selectedList"
closable
@close="removeItemByIndex(index, item)"
>
{{ item.name }}
</el-tag>
<el-table
v-loading="loading"
ref="multipleTable"
:data="tableData"
@select="selectChange"
@select-all="selectAllChange"
>
<el-table-column type="selection" width="55" align="center">
</el-table-column>
<el-table-column prop="ID" label="编号" align="center"> </el-table-column>
<el-table-column prop="name" label="姓名" align="center">
</el-table-column>
<el-table-column prop="age" label="年龄" align="center">
</el-table-column>
</el-table>
<el-row type="flex" class="pageBanner" justify="center">
<el-pagination
background
:total="total"
:page-size="pageSize"
@size-change="pageSizeChange"
@current-change="currentPageChange"
:current-page="currentPage"
:page-sizes="[1, 2, 3]"
layout="total, sizes, prev, pager, next, jumper"
>
</el-pagination>
</el-row>
</div>
</template>
<script>
export default {
data() {
return {
// 唯一标识符
UID: "ID",
loading: false,
total: 0,
pageSize: 3,
currentPage: 1,
selectedList: [
{
ID: 1,
name: "王小虎",
age: 10,
},
],
tableData: [],
};
},
mounted() {
// 页面初始化时,首次加载数据
this.getData(this.currentPage, this.pageSize);
},
methods: {
// 单行前的勾选状态切换
selectChange(selectedRows, row) {
// true为选中, 0或false为取消选中
let selected = selectedRows.length && selectedRows.indexOf(row) !== -1;
if (selected) {
this.addItem(row);
} else {
this.removeItem(row);
}
},
// 全选/取消全选
selectAllChange(selectedRows) {
let selectedMarkList = this.selectedList.map((item) => item[this.UID]);
// 当前页选中行的标记列表
let pageSelectedMarkList = Array.isArray(selectedRows)
? selectedRows.map((item) => item[this.UID])
: [];
this.tableData.forEach((row) => {
if (pageSelectedMarkList.includes(row[this.UID])) {
if (!selectedMarkList.includes(row[this.UID])) {
this.addItem(row);
}
} else if (selectedMarkList.includes(row[this.UID])) {
this.removeItem(row);
}
});
},
// 切换每页显示条数
pageSizeChange(newPageSize) {
this.pageSize = newPageSize;
this.getData(this.currentPage, this.pageSize);
},
// 切换页码--翻页
currentPageChange(newPage) {
this.currentPage = newPage;
this.getData(this.currentPage, this.pageSize);
},
// 更新勾选标记
updateMark() {
let selectedMarkList = this.selectedList.map((item) => item[this.UID]);
this.tableData.forEach((row) => {
if (selectedMarkList.includes(row[this.UID])) {
// toggleRowSelection 需在$nextTick中使用!
this.$nextTick(() => {
this.$refs.multipleTable.toggleRowSelection(row);
});
}
});
},
// 模拟访问接口获取数据
getData(page, pageSize) {
this.loading = true;
setTimeout(() => {
let data = [
{
ID: 1,
name: "王小虎",
age: 10,
},
{
ID: 2,
name: "张三",
age: 20,
},
{
ID: 3,
name: "李四",
age: 30,
},
{
ID: 4,
name: "何香",
age: 18,
},
{
ID: 5,
name: "刘刀",
age: 27,
},
{
ID: 6,
name: "关胜",
age: 33,
},
{
ID: 7,
name: "齐巧",
age: 55,
},
{
ID: 8,
name: "卢一方",
age: 45,
},
{
ID: 9,
name: "王兴海",
age: 66,
},
{
ID: 10,
name: "全德",
age: 100,
},
];
this.total = data.length;
let startIndex = pageSize * (page - 1);
let endIndex = pageSize * page;
this.tableData = data.slice(startIndex, endIndex);
this.updateMark();
this.loading = false;
}, 1000);
},
// 新增选中项
addItem(item) {
this.selectedList.push(item);
},
// 移除选中项
removeItem(item) {
for (let [index, itemTemp] of this.selectedList.entries()) {
if (itemTemp[this.UID] === item[this.UID]) {
this.removeItemByIndex(index);
break;
}
}
},
// 根据下标移除选中项
removeItemByIndex(index, item) {
this.selectedList.splice(index, 1);
// 若有item,则是点击标签上的关闭按钮,移除选中项
if (item) {
this.$nextTick(() => {
this.$refs.multipleTable.toggleRowSelection(
// 此处必须在 tableData 中查找对应的数据,否则 toggleRowSelection 会失效
this.tableData.find((row) => {
return row[this.UID] === item[this.UID];
}),
false
);
});
}
},
},
};
</script>
<style scoped>
.mainBox {
margin: 30px;
}
.el-tag {
margin: 10px;
}
.pageBanner {
margin: 10px;
}
</style>
化为己用
若你的唯一标识符不是 ID
,则修改 data() 中的UID 的值即可!文章来源地址https://www.toymoban.com/news/detail-409383.html
// 唯一标识符
UID: "ID",
到了这里,关于Element UI 多选表格【翻页多选】全能版(含翻页多选数据反显、toggleRowSelection失效的原因解析和解决方案)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!