HarmonyOS鸿蒙Next中makeObserved接口是干嘛的?有什么作用?应该怎么用?
HarmonyOS鸿蒙Next中makeObserved接口是干嘛的?有什么作用?应该怎么用? makeObserved接口是干嘛的?有什么作用?应该怎么用?
一、结论
makeObserved 接口(API version 12 起可用)用于将非观察数据转为可观察数据,适用于三方包类、@Sendable 装饰的类、JSON.parse 返回的对象、collections.Array/Set/Map 等场景。
不支持 undefined和null类型。以及V1 状态装饰器(@State/@Prop)及已被观察的数据,避免双重代理。主要处理的是Object类型,非Object类型,例如基本数据类型number这种,都不支持。
需要注意的是,makeObserved主要针对的是V2的使用场景。因为它是为了解决 @Trace/@ObservedV2 无法覆盖的痛点观察需求。比如从网络请求返回的JSON对象,需要在UI上进行观测操作。就可使用makeObserved。所以V1使用@State就可解决的问题,不用考虑这个。
二、代码实现和详细解释
(1)接口调用 使用及其简单,只需要导入import { UIUtils } from '@kit.ArkUI’进行接口调用接口。麻烦的是识别你的入参是否支持观测监听。
import { UIUtils } from '[@kit](/user/kit).ArkUI';
class UserInfo {
id: number = 0;
}
let observedInfo: UserInfo = UIUtils.makeObserved(new UserInfo());
(2)可从操作的业务场景进行区分,符合以下三种场景一般可操作: 1、三方SDK包中的数据类,这种情况下需要UI可监测,因为无法手动添加@Trace,一般可支持。 【该场景较为简单,参考上面示例即可】
2、@Sendable装饰的类,因为禁止动态修改属性,一般可支持。
import { taskpool } from '[@kit](/user/kit).ArkTS';
import { UIUtils } from '[@kit](/user/kit).ArkUI';
// 定义[@Sendable](/user/Sendable)装饰的类(支持子线程传递)
[@Sendable](/user/Sendable)
class UserInfo {
userId: number = 0;
username: string = 'Guest';
score: number = 0;
isOnline: boolean = false;
// 构造函数初始化数据
constructor(userId: number, username: string) {
this.userId = userId;
this.username = username;
}
}
// 子线程任务:模拟数据处理(如网络请求/复杂计算)
@Concurrent
function processDataInThread(userId: number): UserInfo {
// 模拟耗时操作(子线程执行)
let result = new UserInfo(userId, 'Loading...');
setTimeout(() => {
// 模拟数据更新
result.score = Math.floor(Math.random() * 100);
result.isOnline = true;
}, 1000);
return result;
}
@Entry
@ComponentV2
struct SendableMakeObservedDemo {
// 主线程可观察数据:通过makeObserved包装[@Sendable](/user/Sendable)对象
[@Local](/user/Local) observedUser: UserInfo = UIUtils.makeObserved(new UserInfo(-1, '未登录'));
build() {
Column({ space: 20 })
.width('100%')
.padding(30) {
Text('[@Sendable](/user/Sendable) + makeObserved 演示')
.fontSize(24)
.fontWeight(500)
// 显示用户信息
Text(`用户ID: ${this.observedUser.userId}`)
.fontSize(18)
Text(`用户名: ${this.observedUser.username}`)
.fontSize(18)
Text(`分数: ${this.observedUser.score}`)
.fontSize(18)
Text(`在线状态: ${this.observedUser.isOnline ? '在线' : '离线'}`)
.fontSize(18)
// 触发子线程任务的按钮
Button('加载用户数据(子线程处理)')
.onClick(() => {
// 在子线程执行数据处理
taskpool.execute(processDataInThread, 1001).then((user: UserInfo) => {
// 子线程返回的[@Sendable](/user/Sendable)对象在主线程重新包装为可观察数据
this.observedUser = UIUtils.makeObserved(user);
});
})
// 本地修改数据的按钮(演示可观察性)
Button('本地增加分数')
.onClick(() => {
this.observedUser.score += 10; // 直接修改属性,触发UI刷新
})
}
}
}
3、 JSON.parse返回的匿名对象,一般是网络请求反馈,一般可支持。
import { UIUtils } from '[@kit](/user/kit).ArkUI';
import { JSON } from '[@kit](/user/kit).ArkTS';
// 定义 JSON 数据结构(示例接口)
interface UserData {
name: string;
age: number;
email: string;
}
@Entry
@ComponentV2
struct JsonMakeObservedDemo {
// 原始 JSON 字符串
private rawJson: string = '{"name": "Alice", "age": 25, "email": "alice@example.com"}';
// 使用 makeObserved 包装 JSON.parse 返回的对象
[@Local](/user/Local) observedData: UserData = UIUtils.makeObserved(JSON.parse(this.rawJson) as UserData);
build() {
Column({ space: 30 })
.width('100%')
.padding(30) {
// 显示 JSON 数据
Text('JSON 可观察数据演示')
.fontSize(24)
.fontWeight(500)
Text(`姓名: ${this.observedData.name}`)
.fontSize(18)
Text(`年龄: ${this.observedData.age}`)
.fontSize(18)
Text(`邮箱: ${this.observedData.email}`)
.fontSize(18)
// 修改姓名的按钮
Button('修改姓名为 "Bob"')
.onClick(() => {
this.observedData.name = 'Bob'; // 直接修改属性,触发 UI 刷新
})
// 修改年龄的按钮
Button('年龄 +1')
.onClick(() => {
this.observedData.age++; // 数值类型修改,触发 UI 刷新
})
// 重置为原始数据的按钮
Button('重置数据')
.onClick(() => {
// 重新解析 JSON 并包装为可观察数据
this.observedData = UIUtils.makeObserved(JSON.parse(this.rawJson) as UserData);
})
}
}
}
三、注意
更多关于HarmonyOS鸿蒙Next中makeObserved接口是干嘛的?有什么作用?应该怎么用?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
makeObserved是鸿蒙Next中状态管理装饰器,用于标记可观察的状态变量。当被装饰的变量值发生变化时,会通知所有依赖该变量的UI组件进行自动更新。
主要作用是实现ArkUI声明式UI框架中的数据与视图的响应式绑定。
使用方式:在状态变量前使用@Observed和@makeObserved装饰器。例如:
@Observed
class MyClass {
@makeObserved
count: number = 0;
}
这样当count值改变时,使用该状态的UI会自动刷新。
makeObserved 是 HarmonyOS Next(API 11)中 ArkTS 框架提供的一个关键装饰器,主要用于将对象的属性转换为可观察的(Observable),从而实现数据变更时自动触发UI更新。它是构建响应式UI的核心工具之一。
主要作用
- 建立响应式数据:被
@Observed装饰的类,其属性(包括嵌套对象的属性)的变更可以被UI组件(@Component)观察到。 - 驱动UI自动更新:当被观察的属性值发生变化时,依赖这些数据的UI组件会自动重新渲染,无需手动调用刷新方法。
- 管理对象嵌套:对于复杂对象(对象内包含对象),
@Observed可以确保深层属性的变化也能被观察到。通常与[@ObjectLink](/user/ObjectLink)装饰器配合使用,来同步嵌套对象的变化。
基本用法
- 装饰类:使用
@Observed装饰一个类,这个类的实例属性将成为可观察的。 - 在UI中引用:在UI组件(
@Component)中,通过状态变量(如@State,[@ObjectLink](/user/ObjectLink),@Prop等)引用被@Observed装饰的类实例。
代码示例
// 1. 使用 @Observed 装饰一个类
@Observed
class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
@Entry
@Component
struct Index {
// 2. 在组件中创建被观察的状态变量
@State person: Person = new Person('小明', 25);
build() {
Column() {
// 3. UI绑定会自动响应 person 属性变化
Text(`姓名:${this.person.name}`)
.fontSize(30)
Text(`年龄:${this.person.age}`)
.fontSize(30)
Button('增加年龄')
.onClick(() => {
// 4. 修改属性,UI自动更新
this.person.age += 1;
})
}
.width('100%')
.height('100%')
}
}
与 @ObjectLink 配合处理嵌套对象
当 @Observed 类的属性是另一个 @Observed 类的实例时,需要使用 [@ObjectLink](/user/ObjectLink) 来建立双向同步:
@Observed
class Address {
city: string = '';
}
@Observed
class User {
name: string = '';
address: Address = new Address();
}
@Component
struct AddressView {
[@ObjectLink](/user/ObjectLink) address: Address; // 绑定嵌套对象
build() {
Text(`城市:${this.address.city}`)
}
}
@Entry
@Component
struct Index {
@State user: User = new User();
build() {
Column() {
AddressView({ address: this.user.address }) // 传递嵌套对象
Button('修改城市')
.onClick(() => {
this.user.address.city = '上海';
})
}
}
}
关键注意事项
- 仅装饰类:
@Observed只能装饰类,不能直接装饰普通变量或简单类型。 - 配合状态管理:通常需要与
@State,[@ObjectLink](/user/ObjectLink),@Prop等装饰器一起使用才能生效。 - 性能优化:框架会跟踪依赖关系,仅更新必要的UI组件。
- 不可观察的情况:直接替换整个被观察对象(如
this.person = new Person(...))会触发UI更新,但修改对象内部未用@Observed装饰的深层属性可能无法被检测。
总之,makeObserved(@Observed)是HarmonyOS Next响应式编程的基础,它通过装饰类让对象属性变得可观察,是实现数据驱动UI更新的核心机制。使用时只需装饰数据模型类,并在UI组件中通过状态变量引用即可。

