el-table分页时多选数据的保存和回显

大致思路:

把所有选择的数据全部存到一个大数组中,切页的时候匹配原数据利用ref节点的.toggleRowSelection方法进行回显

具体步骤:

1、勾选和全选时需要判断是选中还是取消,然后更新大数组数据。

2、分页获取新数据之后匹配当前页应该选中的数据,使用 multipleTableRef.value!.toggleRowSelection(row, true);进行回显

所有代码:(示例为前端分页)

html

<template>
  <div style="padding: 20px">
    <el-table
      ref="multipleTableRef"
      :data="tableData"
      @select-all="selectAllChange"
      @select="handleSelectionChange"
    >
      <el-table-column type="selection" width="55" />
      <el-table-column prop="username" label="用户名" show-overflow-tooltip />
      <el-table-column prop="firstName" label="姓名" show-overflow-tooltip />
      <el-table-column prop="email" label="邮箱" show-overflow-tooltip />
    </el-table>
    <!-- 分页器 -->
    <div class="pagination">
      <el-pagination
        v-model:current-page="pagination.pageNum"
        v-model:page-size="pagination.pageSize"
        :page-sizes="[10, 20, 50, 100]"
        layout="total,  prev, pager, next,sizes, jumper"
        :total="pagination.total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>
    <el-button type="primary" @click="yesTo">确 定</el-button>
  </div>
</template>

js

<script setup lang="ts">
import { ref, reactive, nextTick } from "vue";
import { ElMessage } from "element-plus";
import { setUsers } from "../../utils/api";

let listAll: any = []; // 存起来选中的数据
let multipleSelection: any = []; // 当前页选中的数据
const multipleTableRef = ref(); // 表格ref

let tableData = ref<any>([]); // 表格数据
let allList = reactive<any>([]);
//分页器
const pagination = reactive<any>({
  pageNum: 1,
  pageSize: 10,
  total: 0,
});

// 前端分页-切割数据
const paging = () => {
  // 起始位置 = (当前页 - 1) x 每页的大小
  const start = (pagination.pageNum - 1) * pagination.pageSize;
  // 结束位置 = 当前页 x 每页的大小
  const end = pagination.pageNum * pagination.pageSize;
  tableData.value = allList.slice(start, end);
};

// 获取列表数据
const getList = async () => {
  // 接口请求
  allList = [
    {id:1, username: "admin1", firstName: "管理员", email: "123456@163.com" },
    {id:2, username: "admin2", firstName: "管理员", email: "123456@163.com" },
    {id:3, username: "admin3", firstName: "管理员", email: "123456@163.com" },
    {id:4, username: "admin4", firstName: "管理员", email: "123456@163.com" },
    {id:5, username: "admin5", firstName: "管理员", email: "123456@163.com" },
    {id:6, username: "admin6", firstName: "管理员", email: "123456@163.com" },
    {id:7, username: "admin7", firstName: "管理员", email: "123456@163.com" },
    {id:8, username: "admin8", firstName: "管理员", email: "123456@163.com" },
    {id:9, username: "admin9", firstName: "管理员", email: "123456@163.com" },
    {id:10, username: "admin10", firstName: "管理员", email: "123456@163.com" },
    {id:11, username: "admin11", firstName: "管理员", email: "123456@163.com" },
    {id:12, username: "admin12", firstName: "管理员", email: "123456@163.com" },
    {id:13, username: "admin13", firstName: "管理员", email: "123456@163.com" },
    {id:14, username: "admin14", firstName: "管理员", email: "123456@163.com" },
    {id:15, username: "admin15", firstName: "管理员", email: "123456@163.com" },
    {id:16, username: "admin16", firstName: "管理员", email: "123456@163.com" },
    {id:17, username: "admin17", firstName: "管理员", email: "123456@163.com" },
    {id:18, username: "admin18", firstName: "管理员", email: "123456@163.com" },
  ];
  pagination.total = allList.length;
  paging(); 
  toggleSelection(getTurn()); // 回显勾选
};
getList();


// 确认导入
const yesTo = async () => {
  if (listAll.length) {
    listAll = deduplicate(listAll, "username"); //去重
    await setUsers(listAll);
    ElMessage.success("导入成功");
    getList();
  } else {
    ElMessage.warning("请先选择用户!");
  }
};

// 匹配获取当前页应该选中的数据
const getTurn = () => {
  let list: any = [];
  listAll.forEach((v: any) => {
    tableData.value.forEach((s: any) => {
      if (v.username == s.username) list.push(s);
    });
  });
  return list;
};
// 勾选时
const handleSelectionChange = (val: any, item: any) => {
  multipleSelection = val;
  listAll.push(...multipleSelection);
  if (val.includes(item)) {
    //勾选时做的事
  } else {
    //取消勾选时做的事,
    listAll.forEach((v: any, i: number) => {
      if (v.username == item.username) {
        listAll.splice(i, 1);
      }
    });
  }
};
// 全选
const selectAllChange = (val: any) => {
  if (val.length) {
    multipleSelection = JSON.parse(JSON.stringify(val));
    listAll.push(...val);
  } else {
    multipleSelection.forEach((v: any) => {
      listAll.forEach((s: any, i: number) => {
        if (v.username == s.username) {
          listAll.splice(i, 1);
        }
      });
    });
    multipleSelection = [];
  }
};
// 当前页之前勾选过的数据 - 回显
const toggleSelection = (rows?: any) => {
  nextTick(() => {
    if (rows) {
      rows.forEach((row: any) => {
        multipleTableRef.value!.toggleRowSelection(row, true);
      });
    } else {
      multipleTableRef.value!.clearSelection();
    }
  });
};

// 分页事件
const handleSizeChange = (val: number) => {
  pagination.page = 1;
  pagination.limit = val;
  if (listAll.length) {
    listAll = deduplicate(listAll, "username"); //去重
  }
  getList();
};
const handleCurrentChange = (val: number) => {
  pagination.page = val;
  if (listAll.length) {
    listAll = deduplicate(listAll, "username"); //去重
  }
  getList();
};
//  数组去重方法
const deduplicate = (arr: any, t: any) => {
  const newArr = [arr[0]];
  for (let i = 1; i < arr.length; i++) {
    let repeat = false;
    for (let j = 0; j < newArr.length; j++) {
      if (t && arr[i][t] === newArr[j][t]) {
        repeat = true;
        break;
      }
    }
    if (!repeat) newArr.push(arr[i]);
  }
  return newArr;
};
</script>

在使用 element-plus 的 el-table 进行多选时,可以通过绑定一个对象来实现数据回显。具体实现方法如下: 1. 在获取表格数据时,将数据转化为一个以 id 为键,整个数据对象为值的字典对象。 2. 在获取回显数据时,将数据转化为一个以 deviceId 为键,整个数据对象为值的字典对象。 3. 在 el-table 的 @select 事件中,将选中的数据对象存入回显数据字典对象中。 4. 在 el-table 的 @select-all 事件中,遍历所有数据对象,将其存入回显数据字典对象中。 5. 在 el-table 的 :row-selected 事件中,根据回显数据字典对象中是否存在当前数据对象的 id 或 deviceId,来判断当前数据对象是否应该被选中。 具体代码实现可以参考以下示例: ``` <template> <el-table ref="tableRef" :data="tableData" @select="handleSelect" @select-all="handleSelectAll" :row-selected="isRowSelected" row-key="id" > <el-table-column type="selection" width="55" /> <el-table-column type="index" label="序号" width="150" /> <el-table-column prop="name" label="电厂名称" /> </el-table> </template> <script> export default { data() { return { tableData: [], // 表格数据 selectedData: {}, // 回显数据 } }, methods: { // 获取表格数据 async fetchData() { const res = await fetchTableData() this.tableData = res.data.reduce((dic, item) => { dic[item.id] = item return dic }, {}) }, // 获取回显数据 async fetchSelectedData() { const res = await fetchSelectedData() this.selectedData = res.data.reduce((dic, item) => { dic[item.deviceId] = item return dic }, {}) }, // 处理单个选中事件 handleSelect(selection, row) { this.$set(this.selectedData, row.deviceId, row) }, // 处理全选事件 handleSelectAll(selection) { Object.values(this.tableData).forEach(row => { this.$set(this.selectedData, row.deviceId, row) }) }, // 判断行是否被选中 isRowSelected(row) { return !!this.selectedData[row.id || row.deviceId] }, }, mounted() { this.fetchData() this.fetchSelectedData() }, } </script> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值