文章目录
- element plus 层面
- 数据层面
菜鸟好久没写博客了,主要是没遇见什么很难的问题,今天碰见了一个没有思路的问题,解决后立马来和大家伙分享了!
菜鸟今天要实现一个需求,就是:实现跨页面+跨 tab栏 多选!界面如下:
菜鸟一开始感觉毫无头绪,结果没有去百度,直接问 chatGPT 了,chatGPT 直接整了一堆代码,菜鸟试了,一点屁用没有,然后只能百度,按照 csdn 的发现还是不行!
然后出去走了一圈,思来想去,把 chatGPT 的代码注释了一部分,就出效果了,果然还是人类总结的智慧更胜一筹!
这里菜鸟是四个 table 公用一个分页,切换 tab栏 把分页重置为1而已,实现跨页面+跨 tab栏 多选的具体实现:
element plus 层面
其实 element plus 提供了数据变化不改变勾选状态的东西,这里菜鸟记录一下,也方便各位读者:
vue
<!-- :row-key 必须加上 -->
<el-table
ref="table1"
stripe
:data="tableData"
style="width: 100%; height: 100%"
@selection-change="handleSelectionChange"
:row-key="getRowKey"
>
<!-- :reserve-selection="true" 必须加,且要在 type="selection" 上 -->
<el-table-column fixed type="selection" width="55" :reserve-selection="true" />
</el-table>
js
// row-key
function getRowKey(row) {
return row.id
}
数据层面
// 记录每个tab选中的row
const selectedRows = [[], [], [], []]
// 选中的行
let multipleSelection = ref([]) // 用于批量删除
const handleSelectionChange = (val) => {
multipleSelection.value = val
// taskaddpage是区分,因为该组件既是另一个界面又是另一个界面的弹窗;sampleType.value 代表的是tab的值
if (props.taskaddpage) {
selectedRows[sampleType.value] = val
emit('sampleCheck', selectedRows.flat()) // 传扁平化后的数据
}
}
到这里,element plus 就实现完了跨页面+跨 tab栏 多选!
可能看完真的不难,但是没有思路的时候真的很难搞,只要有思路其实都挺简单 !
菜鸟就是被chatGPT的代码搞偏了,所以搞得贼复杂,这里可以把 chatGPT 的回答放这里,反正感觉挺影响思路的:
<template>
<el-tabs v-model="activeTab">
<el-tab-pane label="Tab 1" name="1">
<el-table
:data="currentTableData"
@selection-change="handleSelectionChange"
ref="table1">
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column prop="name" label="Name" width="120"></el-table-column>
<el-table-column prop="age" label="Age" width="120"></el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="Tab 2" name="2">
<el-table
:data="currentTableData"
@selection-change="handleSelectionChange"
ref="table2">
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column prop="name" label="Name" width="120"></el-table-column>
<el-table-column prop="age" label="Age" width="120"></el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="Tab 3" name="3">
<el-table
:data="currentTableData"
@selection-change="handleSelectionChange"
ref="table3">
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column prop="name" label="Name" width="120"></el-table-column>
<el-table-column prop="age" label="Age" width="120"></el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="Tab 4" name="4">
<el-table
:data="currentTableData"
@selection-change="handleSelectionChange"
ref="table4">
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column prop="name" label="Name" width="120"></el-table-column>
<el-table-column prop="age" label="Age" width="120"></el-table-column>
</el-table>
</el-tab-pane>
</el-tabs>
<el-pagination
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-size="pageSize"
:total="total"
layout="total, prev, pager, next">
</el-pagination>
</template>
<script setup>
import { ref, watch, computed, nextTick } from 'vue';
// 当前激活的标签页
const activeTab = ref('1');
// 分页信息
const currentPage = ref(1);
const pageSize = ref(10);
const total = ref(30);
// 模拟的表格数据
const tableData = ref([
{ name: 'John', age: 25 },
{ name: 'Jane', age: 30 },
{ name: 'Tom', age: 35 },
{ name: 'Alice', age: 28 },
{ name: 'Bob', age: 32 },
{ name: 'Charlie', age: 29 },
{ name: 'Dave', age: 45 },
{ name: 'Eve', age: 38 },
{ name: 'Frank', age: 50 },
{ name: 'Grace', age: 26 },
{ name: 'Heidi', age: 33 },
{ name: 'Ivan', age: 27 },
{ name: 'Judy', age: 40 },
{ name: 'Mallory', age: 35 },
{ name: 'Niaj', age: 42 },
{ name: 'Oscar', age: 36 },
{ name: 'Peggy', age: 39 },
{ name: 'Rupert', age: 31 },
{ name: 'Sybil', age: 34 },
{ name: 'Trent', age: 43 },
{ name: 'Victor', age: 44 },
{ name: 'Wendy', age: 37 },
{ name: 'Xander', age: 41 },
{ name: 'Yvonne', age: 30 },
{ name: 'Zach', age: 29 },
]);
// 选中的行
const selectedRows = ref({
'1': [],
'2': [],
'3': [],
'4': [],
});
// 标志位,避免在分页和标签页切换时触发 @selection-change
let isRestoringSelection = false;
// 计算当前页显示的数据
const currentTableData = computed(() => {
const start = (currentPage.value - 1) * pageSize.value;
const end = start + pageSize.value;
return tableData.value.slice(start, end);
});
// 处理表格行选中变化
const handleSelectionChange = (selection) => {
if (!isRestoringSelection) {
selectedRows.value[activeTab.value] = selection;
}
};
// 处理分页变化
const handleCurrentChange = (page) => {
currentPage.value = page;
restoreSelection();
};
// 监听分页变化
watch(currentPage, () => {
loading.value = true;
setTimeout(() => {
loading.value = false;
restoreSelection();
}, 500); // 模拟数据加载延迟
});
// 恢复表格的选中项
const restoreSelection = () => {
nextTick(() => {
const tableRef = activeTab.value === '1' ? table1
: activeTab.value === '2' ? table2
: activeTab.value === '3' ? table3
: table4;
isRestoringSelection = true;
tableRef.value.clearSelection();
selectedRows.value[activeTab.value].forEach(row => {
tableRef.value.toggleRowSelection(row, true);
});
isRestoringSelection = false;
});
};
// 监听标签页切换
watch(activeTab, () => {
restoreSelection();
});
const table1 = ref(null);
const table2 = ref(null);
const table3 = ref(null);
const table4 = ref(null);
</script>
<style>
/* 样式根据需要调整 */
</style>