HarmonyOS 应用开发《掌上英语》第29篇:首页数据聚合——从多个 Manager 到统一的视图模型
首页数据聚合——从多个 Manager 到统一的视图模型引言在实际的 HarmonyOS 应用开发中一个页面往往需要从多个数据源获取数据。例如首页可能需要同时展示今日学习进度来自LearningPlanManager、生词本数量来自NewWordManager、错题列表来自PreferenceUtil以及用户信息来自AppStorageV2。如何协调这些数据源、保持 UI 与数据同步、并在页面加载时正确初始化数据是每个开发者都需要面对的挑战。本文将通过HomePage的代码实例分析多数据源聚合的最佳实践。一、多数据源的整体架构首页HomePage的数据来源如下图所示数据来源数据内容获取方式LearningPlanManager今日学习进度、连续天数单例 Manager 的 getterNewWordManager生词本数量单例 Manager 的 getterPreferenceUtil错题记录列表键值直接读取AppStorageV2用户登录信息全局状态连接HomeVM断点响应式信息ViewModel 单例二、UI 状态管理Local 与 Trace在 ArkTS V2 的组件化架构中Local装饰器用于管理组件级别的状态ComponentV2exportstruct HomePage{homeVM:HomeVMHomeVM.instance;privatelistData:PracticeView[]PRACTICE_LIST_DATA;privatedataSource:PracticeDataSourcenewPracticeDataSource(this.listData);Localfunctions:CourseCoreBar[][newCourseCoreBar($r(app.media.ic_practice_camera),搜单词),newCourseCoreBar($r(app.media.ic__practice_wrong_question),易错词),newCourseCoreBar($r(app.media.ic_practice_star),生词本),newCourseCoreBar($r(app.media.ic_practice_notes),笔记),newCourseCoreBar($r(app.media.ic_chart_report),学习报告)];LocalcoursePractice:CourseQuestions[][newCourseQuestions(CET-4 核心词汇,120,300,85,2025-01-15 14:30),newCourseQuestions(CET-6 高频词汇,1024,3411,85,2025-01-15 14:30),];Localprop:SampleAppStorageV2.connect(Sample,()newSample())!;LocallogoUser:UserInfoAppStorageV2.connect(UserInfo,()newUserInfo())!;}状态管理原则Local管理 UI 状态所有可能被 UI 更新的数据都使用Local或Trace装饰确保状态变更时触发 UI 刷新。AppStorageV2.connect全局用户状态通过 AppStorageV2 连接实现跨页面共享和自动同步。普通属性存业务数据listData等纯配置数据作为普通属性存储不参与状态追踪。三、页面初始化数据流程aboutToAppear是页面生命周期中初始化数据的最佳时机aboutToAppear():void{this.propAppStorageV2.connect(Sample,Sample,()newSample())!;// 其他 Manager 数据的初始化在使用时按需获取}首页中的数据获取是懒加载而非预加载的——数据在各个 Builder 方法中按需从 Manager 读取BuildertodayStudyBuilder(){Column(){Row(){Text(今日学习).fontSize(16).fontWeight(FontWeight.Medium);Text(坚持 7 天)// 从 LearningPlanManager 获取连续天数.fontSize(12).fontColor($r(sys.color.font_secondary)).layoutWeight(1).textAlign(TextAlign.End);}.width(100%).margin({bottom:8});Row(){Text(已学 15 词 / 目标 30 词)// 从 LearningPlanManager 获取进度.fontSize(13).fontColor($r(sys.color.font_secondary)).layoutWeight(1);Text(50%).fontSize(20).fontWeight(FontWeight.Bold).fontColor($r(sys.color.comp_background_emphasize));}.width(100%).margin({bottom:8});Progress({value:15,total:30,type:ProgressType.Linear}).color($r(sys.color.comp_background_emphasize)).height(8).width(100%);}.padding(16).borderRadius(16).backgroundColor($r(sys.color.background_primary));}当前示例中日期数据是硬编码的。在实际项目中应该通过aboutToAppear同步加载aboutToAppear():void{letplanLearningPlanManager.getInstance().getLearningPlan();letprogressLearningPlanManager.getInstance().getTodayProgress();this.learnedCountplan.todayWordCount;this.wordProgressprogress.wordProgress;this.continuousDaysplan.continuousDays;}四、业务数据与 UI 状态的分离一个重要的设计原则是业务数据与 UI 状态分离业务数据层 UI 状态层 ┌──────────────────┐ ┌──────────────────┐ │ LearningPlan │ ──→ │ Local learned │ │ .todayWordCount │ 读取 │ Count: number │ │ │ │ │ │ NewWordManager │ ──→ │ Local wordCount │ │ .getCount() │ 读取 │ : number │ │ │ │ │ │ PreferenceUtil │ ──→ │ onClick 事件中 │ │ .get(key) │ 直接 │ 实时读取 │ └──────────────────┘ └──────────────────┘典型场景——错题练习的点击事件展示了如何在交互发生时实时读取数据而非预加载myWrongPracticeEvent(){// 在点击时实时从 PreferenceUtil 读取letarr:TopicItemType[]PreferenceUtil.getInstance().get(PreferConstant.ERROR_RECORDS,[])asTopicItemType[];if(arr.length0){GlobalContextUtils.showToast({message:暂无易错词汇});return;}// 按时间戳排序最新的排最前面arr.sort((a,b)b.jlStamp-a.jlStamp);letrouterModel:QuestionsRouterModelnewQuestionsRouterModel();routerModel.sourceType错题练习;routerModel.datalistarr;RouterModule.push({url:RouterMap.MY_WRONG_PAGE,param:routerModel});}这种事件触发时读取的模式避免了维护数据的一致性状态特别适合页面跳转传递参数的场景。五、计算属性的数据聚合在某些场景下UI 需要展示的不只是原始数据而是基于原始数据计算出的派生数据。例如学习计划中的进度百分比// 在 LearningPlanManager 中封装计算逻辑publicgetTodayProgress():TodayProgress{letplanthis.getLearningPlan();return{wordProgress:plan.dailyWordGoal0?Math.min(100,Math.floor(plan.todayWordCount/plan.dailyWordGoal*100)):0,listeningProgress:plan.dailyListeningGoal0?Math.min(100,Math.floor(plan.todayListeningDuration/plan.dailyListeningGoal*100)):0,readingProgress:plan.dailyReadingGoal0?Math.min(100,Math.floor(plan.todayReadingDuration/plan.dailyReadingGoal*100)):0};}这样 UI 层只需要展示getTodayProgress()的结果而不需要关心百分比的计算逻辑。六、与 AppStorageV2 的配合全局用户信息通过AppStorageV2.connect连接实现跨页面状态同步// 连接用户信息自动同步登录/登出状态LocallogoUser:UserInfoAppStorageV2.connect(UserInfo,()newUserInfo())!;// 在 UI 中直接使用if(!this.logoUser.isLogin){// 展示未登录提示Image($r(app.media.ic_noLogin))Text(登录后享受更多服务)}else{// 展示学习进度 GridGrid(){/* ... */}}AppStorageV2的connect方法会将指定类型的状态与当前组件关联当全局状态发生变化时如用户登录/登出所有关联的组件自动刷新。七、最佳实践7.1 区分实时读取与状态订阅实时读取用于一次性数据如跳转传参在事件触发时直接从数据源读取。状态订阅用于 UI 中持续展示的数据如学习进度需要将数据同步到Local变量。7.2 使用 ViewModel 管理聚合逻辑当页面逻辑变得复杂时考虑引入 ViewModel 来封装数据聚合逻辑exportclassHomeVM{staticinstance:HomeVMnewHomeVM();gettodayProgress():TodayProgress{returnLearningPlanManager.getInstance().getTodayProgress();}getnewWordCount():number{returnNewWordManager.getInstance().getNewWordCount();}getstudySummary():StudySummary{returnLearningPlanManager.getInstance().getStudySummary();}}7.3 数据初始化时机aboutToAppear适合初始化页面级别的 UI 状态数据。build方法中仅做 UI 布局不要在 build 中执行耗时的数据加载操作。事件回调中适合在用户交互时实时读取数据。八、总结首页的数据聚合展示了 HarmonyOS 应用中多数据源协调的典型模式Manager 管理业务数据和持久化逻辑Local/Trace管理 UI 状态AppStorageV2管理跨页面全局状态Builder 方法按需加载数据。这种分层设计保持了各层的关注点分离使页面代码清晰、可维护同时也为后续的功能扩展提供了良好的架构基础。

相关新闻

2026年横评10款降AI率平台:帮你锁定真正好用靠谱的一款

2026年横评10款降AI率平台:帮你锁定真正好用靠谱的一款

AI写作工具的兴起让论文写作和内容创作变得前所未有的高效,无论是学生还是职场人士,都能借助这些工具快速完成初稿。然而,随着AIGC检测技术的不断升级,问题也随之而来:越来越多的高校、期刊和平台开始严格筛查AI生成内…

2026/7/24 22:49:34 阅读更多 →
Windows XP任务管理器详解与进程管理实战

Windows XP任务管理器详解与进程管理实战

1. Windows XP任务管理器概述Windows XP的任务管理器(Task Manager)是系统内置的进程监控与管理工具,它为用户提供了直观的系统资源使用情况和进程管理界面。与后续版本相比,XP的任务管理器虽然功能相对简单,但其核心设…

2026/7/23 18:11:14 阅读更多 →
Kimi K3 与 Claude Fable5 实测横评:没有全能大模型,只有场景最优解

Kimi K3 与 Claude Fable5 实测横评:没有全能大模型,只有场景最优解

前言大模型已经告别单一模型通吃所有场景的时代。 目前落地效果最好的两款旗舰产品,分别是开放权重路线的 Kimi K3,以及 Anthropic 闭源企业旗舰 Claude Fable5。 很多技术团队在接入 API 时都会陷入选择困境:写代码、解析图纸、审核合同、大…

2026/7/23 14:41:53 阅读更多 →

最新新闻

零基础掌握AI股票分析:3步打造个人智能投资系统

零基础掌握AI股票分析:3步打造个人智能投资系统

零基础掌握AI股票分析:3步打造个人智能投资系统 在信息爆炸的股票市场中,你是否面临这样的困境:每天花费数小时盯盘看新闻,却依然难以把握市场脉络?面对海量数据和技术指标,不知如何筛选有效信息&#xff…

2026/7/24 22:51:06 阅读更多 →
Qwen3.8 上百炼:国产推理 API 这条路,又往前推了一步

Qwen3.8 上百炼:国产推理 API 这条路,又往前推了一步

假设你正在维护一个日调用量几十万甚至上千万的推理 API 服务,你每天担心的无非三件事:GPU 够不够、账单涨不涨、平台稳不稳。 7月23号阿里云出的这条消息——真武M890超节点适配Qwen3.8并上线百炼——正好对应这三件事。咱们拆开看。 先锚定几个事实&am…

2026/7/24 22:51:06 阅读更多 →
算法程序与设计

算法程序与设计

排序四数之和还是从排序开始学习,现在来学习一个经典的问题,四数之和。同时带来一个经典的算法:排序双指针固定前两个数,剩下的两个数用双指针找(和为target - 前两数和)1.将数组排序相同数字挨在一起&…

2026/7/24 22:51:06 阅读更多 →
OmniRoute 踩坑实录:那些文档不会先告诉你的坑

OmniRoute 踩坑实录:那些文档不会先告诉你的坑

上篇我们把手把手把 OmniRoute 跑通了。但用了一段时间,翻了一圈社区和官方排障文档(Troubleshooting / DeepWiki)之后,我得说句实话: 它真香,但"白嫖"和"稳定"之间,全是坑…

2026/7/24 22:51:06 阅读更多 →
[校大]27届江苏师范大学JAVA简历:中厂简历通过率1%

[校大]27届江苏师范大学JAVA简历:中厂简历通过率1%

注:本打分和评价由“校大AI简历”自动生成,仅供参考一、确定校招层次目标江苏师范大学属于排名200以内的优质一本院校,按照“校大”java校招开发岗分层标准,主要以中厂为主。二、简历打分学历小幅加分,主项目直接不合格…

2026/7/24 22:51:06 阅读更多 →
Prompt 测试七大类完整学习指南

Prompt 测试七大类完整学习指南

目录 一、7 类测试定义、学习重点、设计模板、示例 1. 正向问答(基础功能测试) 核心作用 学习重点 测试用例模板 学习实操 2. 边界提问(极限 & 临界场景测试) 核心作用 学习重点 测试模板 核心判断标准 3. 多轮对…

2026/7/24 22:50:06 阅读更多 →

日新闻

用Highcharts 创建可拖拽三维散点立方体3D图表

用Highcharts 创建可拖拽三维散点立方体3D图表

该案例基于Highcharts scatter3d 三维散点图实现空间立方体散点可视化,核心特色:三维 X/Y/Z 三轴空间,所有散点分布在 0~10 立方体空间内;散点使用径向渐变实现立体 3D 圆球质感;支持鼠标 / 触屏拖拽画布,…

2026/7/24 0:00:29 阅读更多 →
AppCertDlls:进程创建路径上的 DLL 入口

AppCertDlls:进程创建路径上的 DLL 入口

AppCertDlls:进程创建路径上的 DLL 入口 AppCertDlls 位于 HKLM\System\CurrentControlSet\Control\Session Manager\AppCertDlls。本文的程序功能是只读列出这个键在 64 位和 32 位注册表视图中的全部值,并显示每条值的来源、名称、类型和可安全显示的数…

2026/7/24 0:00:29 阅读更多 →
我的编程之路:第一篇博客

我的编程之路:第一篇博客

大家好,我是一名编程初学者,同时这也是我编程学习之路上的第一篇博客。在这里,我想要向大家介绍我的一些想法和规划。a.自我介绍我是一个刚刚接触编程的新手,目前在学习c语言,我对编程世界充满了强烈的好奇。当然&…

2026/7/24 0:00:29 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/24 3:59:20 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/24 1:23:39 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/24 18:52:18 阅读更多 →

月新闻