在这里插入图片描述

网罗开发 (小红书、快手、视频号同名)

  大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括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 接入也更自然
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐