ant-design-vue icon indicating copy to clipboard operation
ant-design-vue copied to clipboard

分页组件在当前页仅 1 条数据被删除后,current 值未正确更新(未自动跳转前一页)

Open Caoyn1110 opened this issue 1 month ago • 4 comments

  • [x] I have searched the issues of this repository and believe that this is not a duplicate.

Version

undefined

Environment

vue: "3.4.27", ant-design-vue: "4.2.5", Google Chrome142.0.7444.61, win11

Reproduction link

https://antdv.com/components/pagination

Steps to reproduce

使用 a-pagination 组件时,遇到一个数据同步问题:当当前页仅有 1 条数据,删除该数据后,分页组件的显示状态与 current 绑定值未同步。 复现场景: 初始条件:pageSize=10,total=11,current=2(即第 2 页仅有 1 条数据)。 操作:删除第 2 页的这条数据,此时 total 变为 10(总数据量为 10,刚好 1 页)。 预期:分页组件应自动跳转至第 1 页,且 current 绑定值同步更新为 1。 实际结果:分页组件 UI 显示为第 1 页,但 current 绑定值仍为 2(未双向绑定更新),导致数据与分页状态不一致。

What is expected?

当 当前页仅有 1 条数据,删除该数据导致总数据量减少后: 分页组件的 current 绑定值应自动更新为合理的页码(例如:原当前页为 2,删除后总数据量刚好够 1 页时,current 应变为 1); 分页组件的 UI 显示与 current 绑定值保持一致(即 UI 显示第 1 页,current 值也为 1); 双向绑定生效,外部可通过 current 值获取到最新的当前页状态。

What is actually happening?

当 当前页仅有 1 条数据,删除该数据导致总数据量减少后: 分页组件的 UI 显示会自动切换到前一页(例如:原当前页为 2,删除后 UI 显示第 1 页); 但 v-model:current 绑定的 current 变量值未更新(仍为删除前的 2); 双向绑定失效,外部获取到的 current 值与组件 UI 显示不一致,导致依赖 current 的数据加载等逻辑出错。


删除操作会更新 total 的值,但当 total 减少到 “当前页页码 ×pageSize” 以下时(如当前页 2,pageSize=10,total 变为 10),组件 UI 会切换到第 1 页,但 current 变量的值未自动更新为 1,导致双向绑定失效,数据加载逻辑可能仍基于旧的 current 值执行,引发错误。

Caoyn1110 avatar Nov 07 '25 05:11 Caoyn1110

升级4.2.6就可以了

SpanManX avatar Nov 08 '25 08:11 SpanManX

升级4.2.6就可以了

试了一下 不行呢

Caoyn1110 avatar Nov 11 '25 07:11 Caoyn1110

升级4.2.6就可以了

试了一下 不行呢

有可以复现的demo吗?

SpanManX avatar Nov 11 '25 08:11 SpanManX

升级4.2.6就可以了

试了一下 不行呢

有可以复现的demo吗?

<template>
  <a-table :dataSource="tableData" :columns="columns" :pagination="false" :scroll="{ y: 400 }" size="small" bordered>
    <template #bodyCell="{ text, record, column }">
      <template v-if="column.dataIndex === 'operate'">
        <a-button type="link" size="small" danger @click="del(record)">删除</a-button>
      </template>
    </template>
  </a-table>
  <a-pagination
    showSizeChanger
    showQuickJumper
    show-less-items
    :pageSizeOptions="['5', '10']"
    :defaultPageSize="10"
    v-model:current="current"
    v-model:pageSize="pageSize"
    :total="total"
    @change="handleCurrentChange"
    @showSizeChange="handleSizeChange"
  />
</template>

<script setup lang="ts">
  import { ref, watch } from 'vue';

  const columns = ref([
    {
      title: '姓名',
      dataIndex: 'userName',
    },
    {
      title: '手机号',
      dataIndex: 'phone',
    },
    {
      title: '操作',
      dataIndex: 'operate',
      fixed: 'right',
    },
  ]);

  const data = ref([
    {
      key: '1',
      userName: '张三',
      phone: '13800138000',
    },
    {
      key: '2',
      userName: '李四',
      phone: '13800138001',
    },
    {
      key: '3',
      userName: 'lorem1',
      phone: '13800138002',
    },
    {
      key: '4',
      userName: 'lorem2',
      phone: '13800138003',
    },
    {
      key: '5',
      userName: 'lorem3',
      phone: '13800138004',
    },
    {
      key: '6',
      userName: 'lorem4',
      phone: '13800138005',
    },
    {
      key: '7',
      userName: 'lorem5',
      phone: '13800138006',
    },
    {
      key: '8',
      userName: 'lorem6',
      phone: '13800138007',
    },
    {
      key: '9',
      userName: 'lorem7',
      phone: '13800138008',
    },
    {
      key: '10',
      userName: 'lorem8',
      phone: '13800138009',
    },
    {
      key: '11',
      userName: 'lorem9',
      phone: '13800138010',
    },
  ]);

  const tableData = ref<any>([]);
  const current = ref<number>(1);
  const pageSize = ref<number>(10);
  const total = ref(data.value.length);

  const handleCurrentChange = (page: number, newPageSize: number) => {
    current.value = page;
    pageSize.value = newPageSize;
  };

  const handleSizeChange = (newCurrent: number, size: number) => {
    current.value = newCurrent;
    pageSize.value = size;
  };

  const del = (info: any) => {
    // 从原始数据中删除
    data.value = data.value.filter((item) => item.key !== info.key);
    total.value = data.value.length;

    // 重新计算当前页数据
    updateTableData();
  };

  const updateTableData = () => {
    const start = (current.value - 1) * pageSize.value;
    const end = current.value * pageSize.value;
    tableData.value = data.value.slice(start, end);

    // 如果删除后当前页没有数据且不是第一页,则自动跳转到上一页
    // if (tableData.value.length === 0 && current.value > 1) {
    //   current.value -= 1;
    // }
  };

  watch([() => current.value, () => pageSize.value], updateTableData, {
    deep: true,
    immediate: true,
  });
</script>

<style scoped></style>

写了一个demo

Caoyn1110 avatar Nov 13 '25 07:11 Caoyn1110