返回博客

翻页瞬间过滤条件消失:XtTablePage 分页事件整体覆盖 pageOptions

在某后台管理系统里,一张列表页加了若干筛选条件——下拉选择、级联选择器、日期范围。第一页查得好好的,点第 2 页,接口忽然返回了全量数据。F12 一看请求 payload,过滤字段全部消失。没有报错,没有警告,就像从来没设置过一样。

现象

  • 用户在筛选栏选好条件,点「查询」,第 1 页结果正确
  • 点分页器跳到第 2 页,接口请求里所有自定义过滤字段(typelevelstartTimeendTime 等)全部丢失
  • 数据看起来像「重置筛选」后的结果,但筛选栏的 UI 还显示着已选的值
  • 整个过程零报错,静默失效

根因

XtTablePage / XtTable 的分页器触发 @on-change 时,回调参数是一个只含分页信息的精简对象:

// on-change 回调收到的 val
{ currpage: 2, pagesize: 10 }

问题出在 getData 里的这一行:

getData(val) {
  if (val) {
    this.pageOpitons = val  // ← 整体赋值!
    this.getDatas()
  }
}

this.pageOpitons 本来长这样:

pageOpitons: {
  currpage: 1,
  pagesize: 10,
  type: 'vip',
  level: 2,
  startTime: '2026-01-01',
  endTime: '2026-03-31',
}

一行 this.pageOpitons = val 之后,它变成了:

{ currpage: 2, pagesize: 10 }

所有自定义过滤字段被 JavaScript 引用替换静默抹掉。接口照常发出,只是带着空参数。

坑:整体赋值 pageOptions = val 会把过滤字段一并清空

@on-change 只回传 { currpage, pagesize },用 = 赋值等于把整个对象换掉,之前绑到同一对象上的所有过滤字段全部消失,且没有任何运行时报错。

正解

只从 val 里取分页字段,逐属性写入,保留其余过滤字段:

// 正确写法 —— 只合并分页字段
getData(val) {
  if (val) {
    this.pageOpitons.currpage = val.currpage
    this.pageOpitons.pagesize = val.pagesize
    this.getDatas()
  }
}

如果封装层用的是不同命名(pageNo / pageSize),按实际映射:

getData(val) {
  if (val) {
    this.pageOpitons.pageNo   = val.currpage
    this.pageOpitons.pageSize = val.pagesize
    this.getDatas()
  }
}
正解:逐字段写分页,不整体替换对象引用

只覆盖 currpage / pagesize 两个字段,其他过滤条件安然存活。翻到任意页,过滤参数都会随请求一起带过去。

唯一允许整体赋值的场景:重置

onReset() 里主动清空所有条件是合理的,此时用整体赋值反而正确:

onReset() {
  this.pageOpitons = { currpage: 1, pagesize: 10 }
  this.getDatas()
}

或者用 this.$options.data().pageOpitons 拿初始默认值,效果相同。

排查方法

  1. 在筛选栏选好条件,点查询确认第 1 页正常
  2. 打开 Network,点分页跳到第 2 页
  3. 对比两次请求的 payload——若第 2 次过滤字段消失,找 @on-change 回调
  4. 搜索 this.pageOpitons = val,发现整体赋值即确认根因

一句话外卖

分页事件回调只携带分页字段,永远用逐字段赋值合并,不要整体替换整个查询参数对象。