当前位置: 首页 > 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.dtcms.com/a/332787.html

相关文章:

  • pyecharts可视化图表-pie:从入门到精通(进阶篇)
  • Python 数据可视化:柱状图/热力图绘制实例解析
  • 概率论基础教程第2章概率论公理
  • 享元模式C++
  • 基于深度学习的零件缺陷识别方法研究(LW+源码+讲解+部署)
  • 力扣hot100 | 普通数组 | 53. 最大子数组和、56. 合并区间、189. 轮转数组、238. 除自身以外数组的乘积、41. 缺失的第一个正数
  • 什么才是真正的白盒测试?
  • 专题三_二分_x 的平方根
  • JavaScript 解析 Modbus 响应数据的实现方法
  • 记录处理:Caused by: java.lang.UnsatisfiedLinkError
  • MARCONet++ 攻克中文文本图像超分难题
  • 疯狂星期四文案网第40天运营日记
  • Web 开发 15
  • Transformer实战(11)——从零开始构建GPT模型
  • required a bean of type ‘com.example.dao.StudentDao‘ that could not be found
  • (Arxiv-2025)Stand-In:一种轻量化、即插即用的身份控制方法用于视频生成
  • All Document Reader:一站式文档阅读解决方案
  • LT6911GXD,HD-DVI2.1/DP1.4a/Type-C 转 Dual-port MIPI/LVDS with Audio 带音频
  • 【C++】缺省参数
  • Vue3中的ref与reactive全面解析:如何正确选择响应式声明方式
  • 采购招标周期从2月缩至3周?8Manage招标系统实战案例分享
  • 社区物业HCommunity本地部署二开与使用
  • 我的学习认知、高效方法与知识积累笔记
  • JAVA 关键字
  • Redis 官方提供免费的 30 MB 云数据库
  • 【机器人】人形机器人“百机大战”:2025年产业革命的烽火与技术前沿
  • Linux线程——基于生产者消费者模型的线程同步互斥应用
  • Scikit-learn (sklearn) 库详细介绍
  • 体彩排列三第2025217期号码分析
  • 蓝牙AOA定位技术在医疗行业的创新应用与发展