羽球联盟 HarmonyOS NEXT 实战系列 (15/20):球员动态、关注状态与分类过滤
文章导读球员页同时承担“浏览人物信息”和“维护关注状态”两类任务。关注数据通过StorageLink(follows)直接驱动详情页和个人中心都能共享同一份状态。分类过滤既支持中国队也支持男单、女单、男双、女双、混双等项目维度。页面效果球员动态页比普通列表页更容易暴露状态问题。用户点下关注按钮后既期待当前卡片马上变化也期待个人中心的关注数量跟着变化如果两边不一致这个页面的可信度就会明显下降。从视觉上看这页只是一个带分类 Tab 的球员列表从交互上看它同时连接了人物卡片、关注状态、个人中心统计和详情跳转所以非常适合拿来讲响应式状态和列表过滤是如何配合的。实战拆解PlayerFeedPage最重要的状态不是selected而是StorageLink(follows)。只要关注列表来自 AppStorage当前页的关注按钮、个人中心的关注数量以及未来可能加入的“只看已关注球员”能力看到的就都是同一份数据。相比手动在多个页面里各自维护关注布尔值这种方式更稳也更符合 ArkUI 的数据驱动思路。页面还做了一个很实用的复用设计通过embedded参数控制标题区域。如果球员页被嵌进底部 Tab就展示轻量标题行如果它作为独立页面打开就走完整NavBar。这样列表内容、过滤逻辑和关注逻辑都能复用不需要复制出两套页面。分类过滤部分也值得讲清楚。中国队这个 Tab 使用team 中国队其余项目 Tab 则通过稳定的类别值ms、ws、md、wd、xd过滤。文案面向中文读者逻辑值保持短枚举这样后续无论调整文案还是扩展国际选手都不会让过滤规则变得混乱。关键代码Componentexportstruct PlayerFeedPage{embedded:booleanfalse;Stateselected:number0;StateisRefreshing:booleanfalse;StorageLink(follows)follows:string[][];StorageProp(remote_players)remotePlayers:Player[][];privatetabs:string[][全部,中国队,男单,女单,男双,女双,混双];privatefiltered():Player[]{constsrc:Player[]this.source();if(this.selected0){returnsrc;}if(this.selected1){returnsrc.filter((p:Player)p.team中国队);}constmap:string[][,,ms,ws,md,wd,xd];constcat:stringmap[this.selected];returnsrc.filter((p:Player)p.categorycat);}}这段代码把状态来源和过滤规则都限制在了一个清晰边界内。关注状态由 AppStorage 驱动分类过滤由稳定枚举驱动页面本身只负责把这两类状态投影成卡片列表。取舍分析球员页的核心取舍在于关注状态应该落在页面局部还是落在共享状态里。羽球联盟选择后者是因为关注本身就是跨页面资产而不是单页交互。只要把它当成共享状态处理后续接收藏页、个人中心、详情页统计都会轻很多。另一个取舍是分类维度的组织方式。按国家队和按项目两种分类其实来自不同维度但它们都被收进同一个 Tab 组里。这样做牺牲了一点语义纯粹性却换来了更直接的浏览体验。对当前应用规模来说这种折中是合理的。设计落点关注状态应共享不应只停留在单张卡片内部。分类文案可以面向用户过滤值必须保持稳定且便于扩展。同一业务页通过参数区分嵌入式和独立式展示能显著减少重复代码。易踩坑不要让卡片组件直接操作持久化层关注切换应通过页面或 store 统一处理。不要把分类索引直接当作业务值使用最好有稳定映射表。列表 key 一定要用球员 id不能用 index 代替。验证方式点击球员卡片的关注按钮确认卡片状态和个人中心关注数一起变化。切换中国队、男单、女单等分类确认结果与球员数据类别一致。从 Tab 入口和独立页面入口分别打开球员页确认标题区域符合预期。参考资料ArkUI StorageLink 装饰器ArkUI List 容器ArkUI 自定义组件开发小结第 15 篇要说明的不只是一个球员列表怎么过滤而是共享状态如何让关注行为在多个页面之间保持一致。只要状态来源清晰、过滤规则稳定这类人物流页面就会非常耐扩展。