element plus 实现跨页面+跨tab栏多选

菜鸟好久没写博客了,主要是没遇见什么很难的问题,今天碰见了一个没有思路的问题,解决后立马来和大家伙分享了!

菜鸟今天要实现一个需求,就是:实现跨页面+跨 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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PBitW

可以去掘金看更完善版本

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值