文章导读装备页不仅展示列表还要按球拍、球鞋、球包、配件、穿线等类别切换。远程抓取到的装备数据可能类别不全因此列表页会把本地未覆盖类目补进来。刷新、分类、空态和详情跳转需要在同一页内保持逻辑一致。页面效果装备资讯页的体验目标很明确用户既能快速浏览最新装备内容也能立刻切到自己关心的类别。球拍用户和球鞋用户的关注点不同如果只有一个总列表页面会显得“信息很多但定位很慢”。分类 Tab 在这里不只是视觉切换它直接决定了用户是否愿意继续用这页浏览内容。为了保证类别切换后始终有东西可看项目没有完全依赖远程抓取而是让本地装备数据承担一部分类目兜底职责。实战拆解EquipmentListPage的实现里有一个非常实用的策略如果远程装备列表为空直接使用本地EQUIPMENTS如果远程列表存在就先统计远程已经覆盖了哪些类别再把本地中未被覆盖的类别补到后面。这样一来远程数据能体现时效性本地数据又能保证类别完整度。这个策略特别适合装备场景。因为远程资讯往往更偏新闻流不一定每次都同时覆盖球拍、球鞋、球包、配件、穿线所有类别。如果完全相信抓取结果某些类别切过去就是空白但如果本地兜底补上用户至少还能浏览到稳定的基础内容。页面结构本身保持得很干净顶部是NavBar下面是可滚动的SegmentTab正文区域则在Refresh中渲染列表。分类切换只依赖selected和cats映射不需要在页面里写很多额外状态。换句话说这一页的难点不在 UI而在“如何让远程数据的不完整不会直接伤害界面体验”。关键代码privatesource():Equipment[]{if(this.remoteEquipment.length0){returnEQUIPMENTS;}constremoteCats:SetstringnewSet();for(consteofthis.remoteEquipment){remoteCats.add(e.category);}constsupplement:Equipment[]EQUIPMENTS.filter((e:Equipment)!remoteCats.has(e.category));if(supplement.length0){returnthis.remoteEquipment;}constmerged:Equipment[][];for(consteofthis.remoteEquipment){merged.push(e);}for(consteofsupplement){merged.push(e);}returnmerged;}privatefiltered():Equipment[]{constsrc:Equipment[]this.source();if(this.selected0){returnsrc;}constcat:stringthis.cats[this.selected];returnsrc.filter((e:Equipment)e.categorycat);}这段代码把“远程优先、类目兜底”的思路写得非常清晰。页面不用关心补了哪些项只需要永远基于source()返回的稳定列表去做分类过滤即可。取舍分析这个页面的取舍核心在于你更看重“全都来自最新抓取”还是“分类永远完整”。对于装备类页面完整度往往比绝对新鲜更重要因为用户点进某个类目本质上是在找结构化内容而不是随机新闻流。羽球联盟因此优先保证类目不空再在类目内部追求更新。第二个取舍是分类定义的粒度。项目当前把类别收在球拍、球鞋、球包、配件、穿线五类已经能覆盖主要装备场景。如果继续拆得太细远程抓取补齐的压力会上升页面切换也会变得更碎。适度聚合类别反而能让体验更稳。设计落点装备类页面的“有内容可看”优先级高于“所有内容都来自最新远程抓取”。分类映射应保持稳定枚举便于页面过滤和详情页扩展。远程数据合并策略应在页面入口统一完成而不是散落在各个组件里。易踩坑不要把远程装备列表直接当成唯一数据源否则部分类目会频繁空白。类别值要保持稳定不要一边用中文文案一边用不固定字符串做过滤。列表项跳详情时仍要使用稳定 id不能依赖当前分类索引。验证方式切换球拍、球鞋、球包、配件、穿线等分类确认每个分类都有对应内容。触发下拉刷新后再次切换分类确认远程数据与本地补充仍然正常工作。点击任意装备卡片进入详情确认分类过滤不会影响详情跳转。参考资料ArkUI 自定义组件开发ArkUI List 容器ArkUI Refresh 组件小结第 14 篇真正有价值的地方在于它没有把“远程数据不完整”这个现实问题推给用户而是通过本地类目兜底把页面体验稳住。只要列表入口的合并策略设计得当分类页就能同时兼顾时效性和完整度。