当前位置: 首页 > news >正文

HarmonyOS 实战:用 @Observed + @ObjectLink 玩转多组件实时数据更新

在这里插入图片描述

摘要

在鸿蒙(HarmonyOS)应用开发中,实时数据更新是一个绕不开的话题,尤其是在你封装了很多自定义组件、需要多个组件之间共享和同步数据的场景里。过去我们可能会依赖父子组件直接传参或全局状态管理,但这样写会让代码变得复杂、不易维护。鸿蒙提供了 @Observed@ObjectLink 装饰器,帮我们优雅地实现数据的实时更新和组件联动,开发体验非常顺滑。

引言

现在的鸿蒙应用场景越来越复杂,比如电商的商品详情和购物车同步、聊天应用的实时消息刷新、IoT 应用中的设备状态变更。这些都要求数据能在不同组件间实时更新,而且不能为了同步状态写一堆“搬运代码”。

在日常开发中,@Observed 负责让一个类的实例具备“可观察”的能力,一旦数据变化,引用它的组件就会自动刷新。@ObjectLink 则让子组件能够直接“订阅”父组件传下来的对象变化,而不需要手动再写回调去同步。

下面我们通过一个可运行的 Demo,把这套机制讲清楚。

用 @Observed + @ObjectLink 实现实时数据更新

基本原理

  • @Observed:让一个类的实例变成可观察对象,当它的属性发生变化时,会通知引用它的 UI 组件重新渲染。
  • @ObjectLink:用于子组件属性绑定,让子组件可以感知父组件传入的对象变化。

代码示例

// ViewModel.ts
@Observed
export class MyViewModel {title: string = ""constructor(title: string) {this.title = title}
}// OtherComponent.ets
@Component
export struct OtherComponent {@ObjectLink vm: MyViewModelbuild() {Row() {Text(this.vm.title).fontSize(20).fontWeight(FontWeight.Bold).margin(10)}.width("100%").height(60).backgroundColor("#eeeeee").justifyContent(FlexAlign.Center).alignItems(VerticalAlign.Center)}
}// MyComponent.ets
@Entry
@Component
export struct MyComponent {@State vm: MyViewModel = new MyViewModel("初始标题")build() {Column() {OtherComponent({ vm: this.vm }).onClick(() => {this.vm.title = "标题已更新 " + new Date().toLocaleTimeString()})Button("点击更新标题").margin(10).onClick(() => {this.vm.title = "按钮触发更新 " + new Date().toLocaleTimeString()})}.width("100%").height("100%")}
}

代码解析

MyViewModel

  • @Observed 修饰,让它的属性具备响应式更新能力。
  • 改变 title 会自动触发 UI 组件刷新。

OtherComponent

  • @ObjectLink 接收父组件传入的 vm,并实时订阅它的变化。
  • 不需要手动写事件监听,只要数据变化,UI 就会刷新。

MyComponent

  • @State 声明一个可响应的 MyViewModel 实例,并传给子组件。
  • 父组件点击区域或者按钮都会修改 vm.title,从而触发子组件刷新。

场景应用

场景 1:商品详情与购物车同步

描述:在电商应用中,用户在商品详情页修改购买数量,购物车组件的数量显示也需要立刻变化。

实现思路

  • 将商品数量信息放到一个 @Observed 的 ViewModel 中。
  • 详情页和购物车组件通过 @ObjectLink 共享这个 ViewModel。
@Observed
export class CartItem {count: number = 1
}@Component
export struct ProductDetail {@ObjectLink item: CartItembuild() {Column() {Button("增加数量").onClick(() => this.item.count++)}}
}@Component
export struct CartBar {@ObjectLink item: CartItembuild() {Text("数量: " + this.item.count)}
}

场景 2:聊天应用的实时消息

描述:在聊天页面发送消息,消息列表组件应当实时刷新。

实现思路

  • @Observed 包装一个 MessageList,内部是一个数组。
  • 消息输入框组件发送消息后,直接修改 MessageList,消息列表组件自动更新。
@Observed
class MessageList {messages: string[] = []
}@Component
struct ChatInput {@ObjectLink msgList: MessageListbuild() {Button("发送").onClick(() => {this.msgList.messages.push("新消息 " + Date.now())})}
}@Component
struct ChatList {@ObjectLink msgList: MessageListbuild() {Column() {ForEach(this.msgList.messages, (msg) => Text(msg))}}
}

场景 3:IoT 设备状态面板

描述:多个组件显示同一设备的温度、湿度、电池电量,任意组件更新数据时其他组件同步变化。

实现思路

  • @Observed 包装 DeviceStatus 对象。
  • 传递给各个子组件,通过 @ObjectLink 绑定。

QA 环节

Q1:@Observed 和 @State 有什么区别?

  • @Observed 用于类的实例,使它变成可观察对象,适合跨组件共享。
  • @State 用于组件内的变量,适合管理本地状态。

Q2:为什么要用 @ObjectLink,而不是直接传值?

  • 直接传值是浅拷贝,不会触发子组件刷新。
  • @ObjectLink 会建立对象引用,保证数据变化实时传递。

Q3:如果多个组件要共享数据,该怎么组织?

  • 建议抽一个 ViewModel,用 @Observed 修饰,在需要的地方通过 @ObjectLink 引用。

总结

在鸿蒙应用开发中,@Observed + @ObjectLink 是处理实时数据更新的“黄金搭档”。它们的组合能让我们轻松在多个组件间同步数据,而不用手动写一堆事件监听或状态同步逻辑。在实际项目中,不管是电商、聊天还是 IoT 应用,这套模式都能极大减少代码量,提高可维护性。

如果你现在的项目中有多个自定义组件需要共享数据,这套方法可以直接用起来,几乎不需要额外改动架构。

http://www.lryc.cn/news/621795.html

相关文章:

  • Go从入门到精通系列学习路线规划
  • Day62--图论--97. 小明逛公园(卡码网),127. 骑士的攻击(卡码网)
  • 智能家居【home assistant】(一)-在Windows电脑上运行home assistant
  • 论文阅读:基于大语言模型的多机器人任务分配与调度的自动 MILP 模型构建
  • GitHub 上 Star 数量前 18 的开源 AI Agent 项目
  • 基于uiautomation的自动化流程RPA开源开发演示
  • Linux网络基础(一)
  • 【补充】数据库中有关系统编码和校验规则的简述
  • 【软件设计模式】前置知识类图、七大原则(精简笔记版)
  • 【SpringBoot】SpringBoot 整合JDBC、Mybatis、Druid
  • Cursor/VSCode/VS2017 搭建Cocos2d-x环境,并进行正常的调试和运行(简单明了)
  • 基于MATLAB的机器学习、深度学习实践应用
  • WPF 监控CPU、内存性能
  • 物联网(IoT)系统中,通信协议如何选择
  • linux下找到指定目录下最新日期log文件
  • Webapi发布后IIS超时(.net8.0)
  • 【微服务】.NET8对接ElasticSearch
  • 华为实验综合小练习
  • 从源码到可执行文件:hello.c 的二进制之旅
  • Python从入门到高手9.3节: 利用字典进行格式化
  • GoLand深度解析:智能开发利器与cpolar内网穿透方案的协同实践
  • 配置国内加速源后仍然无法拉取镜像
  • Vue2与Vue3生命周期函数全面解析:从入门到精通
  • 【自动驾驶】自动驾驶概述 ② ( 自动驾驶技术路径 | L0 ~ L5 级别自动驾驶 )
  • Linux软件编程(五)(exec 函数族、system、线程)
  • Unity导航寻路轨迹可视化实现
  • Unity_数据持久化_Json
  • Ubuntu DNS 综合配置与排查指南
  • 小程序上拉加载下一页数据
  • 基于HTML5与Tailwind CSS的现代运势抽签系统技术解析