el-pagination切换分页调用两次分页接口问题

Daotin 于 2024-03-02 发布 编辑

问题

我们一般会在 el-pagination 触发 size-change 和 current-change 的时候,都会重新调用分页接口。

那么当数据有 51 条,size=10,page=6,也就是最后一页的时候,缺环分页为 size=50 后,会触发两次分页接口:

那么,当数据量比较大,接口返回很慢的时候,就会出现第一次的调用结果晚到,导致结果不对。

分析

我们可以做一些优化方案:

方案一:

每次切换 size 后,el-pagination 会发现页码不够,自动定位到最后一页,等其定位好后,再进行搜索。

优点:两次的结果是相同的,因为搜索的参数相同了

缺点:依然会搜索两次

方案一(优化)

在方案一的基础上,加入防抖功能,避免两次调用。

export function debounce(func, wait, immediate) {
  let timeout, args, context, timestamp, result

  const later = function() {
    // 据上一次触发时间间隔
    const last = +new Date() - timestamp

    // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
    if (last < wait && last > 0) {
      timeout = setTimeout(later, wait - last)
    } else {
      timeout = null
      // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
      if (!immediate) {
        result = func.apply(context, args)
        if (!timeout) context = args = null
      }
    }
  }
}

方案二:(⭐ 推荐)

每次切换分页大小,定位到第 1 页。

在 handleSizeChange 里面,将 currentPage = 1(使用 js 手动设置 currentPage,不会触发 handleCurrentChange),由于不管怎么切换分页,第一页永远存在,所以不会触发 handleCurrentChange,只会触发一次接口请求。

优点:只会调用 1 次

缺点:每次切换分页都会定位到第 1 页

方案三:

优化不定位到第 1 页,而是页码不够的时候定位到第 1 页。

这个需要后端分页接口加个参数,当有这个参数的时候,分页只查询总数和总页数。

如果当前的页码小于总页数,则不改变页码定位,否则定位到第 1 页。

优点:不用每次定位到第 1 页

缺点:每次切换分页(分页调大的时候)都会调用两次分页接口

隐藏的问题

目前以上的方式都还有有一个隐藏的问题。比如获取最后一页的数据需要 10s,获取第一页的数据需要 2s,如果用户操作很快(先点击最后一页,再点击第一页),必然会出现第一次获取的数据晚到的情况。

但是,由于我们会在接口返回值后,将当前 currentPage 设置为返回值,实际上最后用户看到的还是最后一页的数据。

如果还有避免这种点击了第一页,但是最后还在最后一页的情况,办法就是在返回结果前,禁用第一页的点击。