鸿蒙 App 的数据流设计
数据流 = 数据从哪里来,经过哪里,最终到哪里去用户操作↓触发逻辑↓获取数据(网络 / 本地)↓状态更新↓UI 渲染网络数据缓存数据本地数据库AI 结果设备数据(传感器)一旦没有清晰的数据流设计: Bug 会非常难查数据流没有设计好。

大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。
图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG
我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。
展菲:您的前沿技术领航员
👋 大家好,我是展菲!
📱 全网搜索“展菲”,即可纵览我在各大平台的知识足迹。
📣 公众号“Swift社区”,每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。
💬 微信端添加好友“fzhanfei”,与我直接交流,不管是项目瓶颈的求助,还是行业趋势的探讨,随时畅所欲言。
📅 最新动态:2025 年 3 月 17 日
快来加入技术社区,一起挖掘技术的无限潜能,携手迈向数字化新征程!
文章目录
引言
很多鸿蒙应用一开始都很简单:
页面请求数据 → 渲染 UI → 完成
但随着项目变大,你很快会遇到这些问题:
- 数据更新了,但 UI 没刷新
- 多个页面状态不一致
- 网络数据、缓存数据、内存数据混在一起
- AI 功能接入后,数据流彻底混乱
这时候你会发现:
问题不在 UI,而在“数据是怎么流动的”。
数据流,才是一个 App 是否稳定、可扩展的关键。
一、什么是数据流?
简单来说:
数据流 = 数据从哪里来,经过哪里,最终到哪里去
在鸿蒙应用中,一个完整的数据流通常是:
用户操作
↓
触发逻辑
↓
获取数据(网络 / 本地)
↓
状态更新
↓
UI 渲染
看起来很简单,但复杂项目里,数据来源会变多:
网络数据
缓存数据
本地数据库
AI 结果
设备数据(传感器)
一旦没有清晰的数据流设计: Bug 会非常难查
二、鸿蒙常见的数据流问题
先看几个真实开发中经常踩的坑。
1 数据来源混乱
// 页面直接请求
this.data = await http.get()
// Service 里也请求
this.service.getData()
// Repository 也在请求
this.repo.fetch()
问题:
- 数据来源不唯一
- 很难统一管理
2 状态分散
@State dataA
@State dataB
@State dataC
不同页面各自维护一套状态: 数据不同步
3 UI 直接操作数据
this.list.push(item)
问题:
- 无法追踪数据变化
- UI 状态不可预测
三、一个好的数据流应该具备什么?
一个设计良好的数据流,应该具备:
1 单向流动
Data → State → UI
而不是:
UI ↔ Data(双向混乱)
2 单一数据源
Single Source of Truth
3 可追踪
每一次数据变化,都可以知道:
谁改的?
什么时候改的?
为什么改?
四、推荐的数据流架构
在鸿蒙应用中,推荐采用类似这样的结构:
UI Layer
↓
ViewModel / State
↓
UseCase / Service
↓
Repository
↓
DataSource(Network / DB / Cache)
五、分层详解 + 代码示例
1 UI 层(ArkUI)
UI 层只负责:
展示数据
触发事件
示例:
@Entry
@Component
struct UserPage {
@State user = null
vm: UserViewModel = new UserViewModel()
aboutToAppear() {
this.vm.loadUser()
}
}
UI 不直接请求数据
2 ViewModel / 状态层
负责:
管理状态
驱动 UI 更新
示例:
export class UserViewModel {
@Observed user = null
async loadUser() {
this.user = await userService.getUser()
}
}
所有 UI 状态集中在这里
3 Service / UseCase 层
负责:
业务逻辑
数据组合
示例:
export class UserService {
async getUserProfile() {
const user = await userRepo.getUser()
const orders = await orderRepo.getOrders(user.id)
return { user, orders }
}
}
4 Repository 层
负责:
数据来源统一
缓存策略
示例:
export class UserRepository {
async getUser() {
const cache = await cache.get("user")
if (cache) return cache
const data = await api.get("/user")
cache.set("user", data)
return data
}
}
统一数据入口
5 DataSource 层
负责:
真正的数据获取
例如:
export class ApiClient {
async get(url: string) {
return fetch(url)
}
}
六、AI 场景下的数据流变化
当接入 AI 后,数据流会发生变化:
传统数据流
UI → Service → Repository → Data
AI 数据流
用户输入
↓
AI(解析意图)
↓
Service / Tool
↓
Repository
↓
数据返回
↓
UI 展示
示例代码
export class AIService {
async handle(input: string) {
const intent = await this.parse(input)
if (intent === "user") {
return await userService.getUser()
}
if (intent === "order") {
return await orderService.getOrders()
}
}
}
数据流不再由 UI 驱动,而是由 AI 驱动。
七、关键设计:状态管理
鸿蒙 ArkUI 中的状态机制:
@State
@Observed
@ObjectLink
推荐做法
状态只存在一个地方:
ViewModel / Store
错误写法
PageA 自己维护一份
PageB 再维护一份
正确写法
export class GlobalStore {
@Observed user = null
}
多个页面共享:
@ObjectLink store: GlobalStore
八、数据流设计的进阶优化
1 引入 Store(全局状态)
适用于:
用户信息
登录状态
主题配置
2 引入事件流(Event Bus)
适用于:
跨模块通信
3 引入缓存策略
例如:
内存缓存
磁盘缓存
过期策略
4 数据不可变(推荐)
避免:
this.list.push()
改为:
this.list = [...this.list, newItem]
更容易追踪变化
九、完整数据流示意
用户点击 / AI 输入
↓
ViewModel
↓
Service
↓
Repository
↓
DataSource
↓
返回数据
↓
更新 State
↓
UI 渲染
总结
很多鸿蒙应用的问题,其实都不是 UI 问题,而是:
数据流没有设计好。
记住三个核心原则:
1 单向数据流
Data → State → UI
2 单一数据源
不要多个地方同时改数据
3 UI 只负责展示
不要让 UI 参与业务逻辑
当你把数据流设计清楚之后,你会发现:
- Bug 明显减少
- 状态更稳定
- AI 接入也更自然
更多推荐


所有评论(0)