写移动端列表时,我会先盯一个小地方。下拉刷新和触底加载会不会打架。

Web 后台分页的入口很清楚。用户点分页器,页码变化,重新请求。UniApp 页面不一样。用户手指一滑,可能触发下拉刷新;继续往下滑,又可能触发触底加载。网络慢一点,两个请求先后回来,列表状态就容易乱。

Codex 如果只按 currentsize 写分页,它能写出一个看起来完整的列表。真正滑起来以后,问题才会出现。

移动端分页先分清两个动作

下拉刷新和触底加载都在请求列表,但两个动作的目标完全不同。

下拉刷新要回到第一页。它通常要重置页码、重置是否还有下一页、重新提交查询条件,并决定旧列表是否立刻清空。

触底加载要接着当前列表往后拼。它不能重置列表,也不能在没有更多数据时继续请求。它还要防止用户连续触底,短时间内发出两次下一页请求。

这两个动作如果都调用同一个 getList,参数里就要说清楚当前是哪一种动作。只写一个无参 getList(),Codex 很容易在函数内部凭感觉判断。感觉写出来的分页,最怕碰到慢请求。

requestState 要真管住请求

uni-wx 里提到 xt-pagelistData.pageObj,推荐字段里有 requestStatehasNextcurrentsizetotal。这些字段要负责控制列表行为,不能只把对象补完整。

requestState 要能回答页面现在是否正在请求。正在请求时,触底加载应该停住。否则用户滑到底部,页面可能连续发两次同页请求。后回来的那次如果再拼到列表里,重复数据就来了。

hasNext 要能回答后面还有没有数据。已经没有下一页时,触底入口应该直接返回。继续请求没有意义,还会把空响应当成异常处理。

current 要能回答下一次请求哪一页。刷新时它回到第一页,触底时它进入下一页。这个字段如果在请求前后时机不清楚,失败后会很麻烦。请求第二页失败了,当前页到底算第一页,还是已经变成第二页,这个决定会影响下一次触底。

我会要求 Codex 在写代码前先说清这些字段的更新时机。

旧响应覆盖新列表是隐藏问题

移动端列表还有一个不太明显的问题。旧请求可能晚回来。

用户进入页面,第一页请求发出去了。网络还没回来,他下拉刷新,又发了一次第一页请求。第二次请求先返回,页面展示了新列表。第一次请求后来才返回,如果代码没有识别请求顺序,它可能把旧数据重新写回去。

这个问题在后台分页里也有,但移动端更常见,因为刷新和触底是手势触发,用户不会等按钮恢复以后再操作。

Codex 写列表时,不能只关心接口成功后怎么赋值。它要说明旧响应是否会被丢弃,或者至少要保证同一时刻只有一个列表请求在跑。项目里如果已有 useTableMixin,就先查它怎么处理请求状态;没有确认前,不要自己把请求并发放开。

空状态要等状态稳定以后再显示

移动端列表的空状态也容易写早。

页面刚进入时,列表为空。这个时候如果直接写 list.length === 0 就展示 xt-noData,用户会先看到空状态闪一下,然后数据才出来。接口失败时,列表也可能为空,它和正常空数据要分开处理。

我会把空状态拆成三种。

状态 页面该怎么理解
首次加载中 不展示正常空状态,等待请求结束
正常空列表 请求成功,第一页没有数据,可以展示 xt-noData
请求失败 展示错误提示或重试入口,不能当成正常无数据

xt-noData 能统一空状态展示,但它不能替页面判断为什么空。判断仍然要靠请求状态、页码和接口结果。

失败恢复要讲清当前页

触底加载失败以后,页面不该把旧列表清掉。旧列表是用户已经看到的内容,要保留。问题在于当前页怎么恢复。

一种写法是在请求成功后再更新 current。请求第二页成功,current 才变成 2。失败时仍停在 1,下一次触底继续请求第二页。

另一种写法是在请求前先把 current 加一。这样失败时必须回滚,否则下一次触底会跳到第三页。

两种写法都能用,但 Codex 必须选一种并写清楚。它不能在刷新时先改页码,在触底时又后改页码。时机混乱以后,列表会漏页或重复页。

交给 Codex 前我会先问这几个问题

移动端列表任务开始前,我会让 Codex 先回答这些问题。

问题 目的
刷新时是否清空旧列表 决定用户看到旧内容还是空白等待
触底时如何防重复请求 防止同页重复拼接
当前页在请求前还是请求后更新 决定失败后是否需要回滚
没有更多数据时怎么停住 防止无意义请求
首次加载、正常空、失败空怎么区分 防止 xt-noData 显示错
是否复用 useTableMixin 优先遵守项目已有列表逻辑

这些问题答完,再让 Codex 写页面,列表才会稳一点。

验收要多做几组连续动作

我验收 UniApp 列表分页,会连续做几组动作。

首次进入页面,看加载状态和第一页数据。下拉刷新一次,看页码是否回到第一页。快速触底两次,看是否只发一次下一页请求。模拟没有更多数据,看触底是否停住。模拟接口失败,看旧列表是否保留、加载状态是否关闭、下一次操作是否还能继续。

这些动作比只看“列表能加载下一页”更接近移动端真实使用。

uni-wx 在这里提供的是项目规则入口。xt-pagepageObjuseTableMixinxt-noData 都是线索。Codex 要先顺着这些线索读项目,再写自己的逻辑。移动端列表要重新处理刷新、触底和状态恢复,不能只把后台分页器藏起来。

下一篇我会把这套判断整理成一份可以直接交给 Codex 的移动端列表任务模板。

本系列持续更新。写移动端时,我会继续把重点放在可验证的页面行为上。

Logo

葡萄城是专业的软件开发技术和低代码平台提供商,聚焦软件开发技术,以“赋能开发者”为使命,致力于通过表格控件、低代码和BI等各类软件开发工具和服务,一站式满足开发者需求,帮助企业提升开发效率并创新开发模式。

更多推荐