本文档归纳 uni-app + Vue3 在「分页加载、滚动触底加载、列表与固定底栏」等场景下的可复用思路;客户端、供应商端、配送员端技术栈一致,均可套用(差异主要在接口与业务字段)。下文第 8 节为供应商/配送员端当前实现扫描与改造优先级。
| 状态 | 用途 |
|---|---|
loading |
首屏或整表刷新(reset = true) |
loadingMore |
触底加载下一页(reset = false) |
page / nextPage |
当前或下一页页码 |
hasMore |
是否还有下一页 |
total / totalPages(可选) |
服务端分页元信息 |
原则:首屏与「加载更多」不要共用一个布尔值,避免触底时把整页打成骨架屏,或重复并发请求。
fetchList(reset: boolean)
reset === true:page = 1,清空 list,走首屏 loading。reset === false:在 !loadingMore && hasMore guard 下请求 nextPage,结果 concat 到 list。onShow:按业务决定是每次都 fetchList(true),还是仅首次进入刷新。fetchList(true) 整表刷新;若列表项有稳定 id 且接口支持,也可局部更新单条以省流量。totalPages、total + pageSize 判断 currentPage < totalPages。totalPages,可用「本页条数 === pageSize」近似推断可能还有下一页(最后一页不满 pageSize 时自然停止)。适用于「列表页要分页,其它页面仍要全量」的场景(如收货地址)。
约定示例:
page(或不传分页参数):响应为 数组 [],供选地址、下单、购物车等沿用旧逻辑。page(及 pageSize):响应为 对象{ list, total, page, pageSize, totalPages }。注意:各调用方只在自己需要的形态下传参;列表页专用分页结构,避免全局把 data 当成数组解析。
@scrolltolower 触底加载。scroll-view 同时滚动(手势冲突、高度异常)。页面根(flex 列、占满可视高度)
├── 可选:顶部固定区(标题、筛选)
├── scroll-view(flex:1,列表-only)
│ └── 列表项 … + 底部「没有更多了」提示
└── 固定底栏(按钮区,在 scroll-view 外)
pages.json 的配合若整页不应跟手滚动、仅内部区域滚动,可为该页配置 disableScroll: true(按 uni-app 文档与项目现状使用),减少双滚动问题。
scroll-view 与 Flex 的常见坑scroll-view 同时 flex: 1 又写 height: 100%:在部分端上高度计算异常,表现为内容被裁切、触底不触发、scrolltolower 不稳定。flex: 1; min-height: 0(必要时 flex-basis: 0),把剩余高度交给 scroll-view,由 flex 约束高度而不是与 height: 100% 打架。在 H5 或模拟器上,固定顶/底栏可能被 导航栏、tabBar 遮挡。
top: var(--window-top) 等(按 uni-app 环境变量文档使用)。bottom: var(--window-bottom, 0px) 或与 tabBar 高度策略一致。若仍有个别机型异常,再评估该页 navigationStyle: custom 等方案。
loading / loadingMore 分离,触底有防抖或 guard,避免重复请求。hasMore 优先用 totalPages,有兜底逻辑。scroll-view 内,主按钮在 scroll-view 外固定。min-height: 0,避免 scroll-view 高度为 0 或 100% 冲突。disableScroll,仅内部滚动。--window-top / --window-bottom 避让系统 UI。以下文件曾按上述思路调整,可作对照阅读(以仓库当前版本为准):
totalPages 与触底加载。scroll-view + 底部固定「新增」+ 地址分页;其它页面对地址接口仍用全量数组形态。以下基于仓库内 miniprogram/src/pages/supplier、miniprogram/src/pages/deliverer 的只读扫描(接口若后续扩展分页,前端按第 1~2 节模式对接即可)。
| 优先级 | 页面路径 | 现状摘要 | 建议 |
|---|---|---|---|
| P0 | supplier/quotation/quotation.vue |
仅请求 page=1&pageSize=50;列表每条再请求报价详情以计算已报/未报数量(N+1) |
① 列表接口分页 + 触底加载;② 优先让列表接口直接带 quotedCount / unquotedCount(或等价字段),避免每条再打详情接口 |
| P1 | supplier/delivery/delivery.vue |
page=1&pageSize=50,有纵向 scroll-view,无加载更多 |
分页 + @scrolltolower;若将来底部有固定操作区,按第 3 节拆出固定底栏 |
| P1 | supplier/address/address.vue |
取货地址全量 GET,普通 view 列表 + 底部按钮 |
与客户端地址一致:可选 双形态接口 + scroll-view + 固定「新增」+ 分页(地址多时避免底栏被顶没) |
| P2 | supplier/price-list/price-list.vue |
全量列表,无 scroll-view |
数据量上来后加分页与可滚动列表壳 |
| 另注 | supplier/inquiry/inquiry.vue |
先拉「当前询价单」再拉详情 整单商品(非典型长列表分页) | 文档中的「双栏各自滚动、Flex 高度」仍可借鉴;若单询价商品极大,再考虑后端商品维度分页 + 前端滚动加载 |
| 优先级 | 页面路径 | 现状摘要 | 建议 |
|---|---|---|---|
| P0 | deliverer/snatch/snatch.vue |
page=1&pageSize=20,无第二页;scroll 使用 height: 100vh |
确认后端 totalPages 后做触底加载;布局上注意第 4 节(100vh 与 flex / 安全区) |
| P1 | deliverer/task/task.vue |
page=1&pageSize=50,有 scroll-view |
与客户端订单列表同一套:分页元数据 + loadingMore + scrolltolower |
| P2 | deliverer/home/home.vue |
首页内嵌任务列表,同样 page=1&pageSize=50 |
首页可保持「摘要条数」或较小 pageSize;完整列表以 task 页为准即可 |
pages.json 提示供应商、配送员列表页当前多数 未 设置 disableScroll: true。若在具体页出现整页与 scroll-view 双滚动,再按第 3.3 节为该页单独打开。
文档版本:客户端分页与布局实践;补充 2026 年供应商/配送员端扫描与优先级。