0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

HarmonyOS 5 makeObserved接口详解

HarmonyOS解决方案 来源:HarmonyOS解决方案 作者:HarmonyOS解决方案 2025-06-16 17:58 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

HarmonyOS 5】makeObserved接口详解

##鸿蒙开发能力 ##HarmonyOS SDK应用服务##鸿蒙金融类应用 (金融理财#

一、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就可解决的问题,不用考虑这个。

二、makeObserved如何使用?

(1)接口调用
使用及其简单,只需要导入import { UIUtils } from '@kit.ArkUI'进行接口调用接口。麻烦的是识别你的入参是否支持观测监听。

import { UIUtils } from '@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.ArkTS';
import { UIUtils } from '@kit.ArkUI';

// 定义@Sendable装饰的类(支持子线程传递)
@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对象
  @Local observedUser: UserInfo = UIUtils.makeObserved(new UserInfo(-1, '未登录'));

  build() {
    Column({ space: 20 })
      .width('100%')
      .padding(30) {
        
        Text('@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对象在主线程重新包装为可观察数据
              this.observedUser = UIUtils.makeObserved(user);
            });
          })
        
        // 本地修改数据的按钮(演示可观察性)
        Button('本地增加分数')
          .onClick(() = > {
            this.observedUser.score += 10; // 直接修改属性,触发UI刷新
          })
      }
  }
}

3、 JSON.parse返回的匿名对象,一般是网络请求反馈,一般可支持。

import { UIUtils } from '@kit.ArkUI';
import { JSON } from '@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 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);
          })
      }
  }
}

三、注意

  1. getTarget问题
    通过getTarget获取原始对象后修改属性,不会触发UI刷新(需操作代理对象)
  2. 兼容性错误
    与@State等V1装饰器混用会抛异常,需使用V2装饰器(@Local/@Provide等)

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 接口
    +关注

    关注

    33

    文章

    9443

    浏览量

    156109
  • HarmonyOS
    +关注

    关注

    80

    文章

    2146

    浏览量

    35537
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    HarmonyOS 5】鸿蒙应用隐私保护详解

    HarmonyOS 5】鸿蒙应用隐私保护详解 ##鸿蒙开发能力 ##HarmonyOS SDK应用服务##鸿蒙金融类应用 (金融理财# 一、前言 在今天这个手机不离手的时代,我们每天
    的头像 发表于 07-11 18:30 941次阅读

    HarmonyOS 5】鸿蒙中常见的标题栏布局方案

    HarmonyOS 5】鸿蒙中常见的标题栏布局方案 ##鸿蒙开发能力 ##HarmonyOS SDK应用服务##鸿蒙金融类应用 (金融理财# 一、问题背景: 鸿蒙中常见的标题栏:矩形区域,左边
    的头像 发表于 07-11 18:30 635次阅读
    【<b class='flag-5'>HarmonyOS</b> <b class='flag-5'>5</b>】鸿蒙中常见的标题栏布局方案

    HarmonyOS 5】鸿蒙中进度条的使用详解

    HarmonyOS 5】鸿蒙中进度条的使用详解 ##鸿蒙开发能力 ##HarmonyOS SDK应用服务##鸿蒙金融类应用 (金融理财# 一、Ha
    的头像 发表于 07-11 18:26 709次阅读
    【<b class='flag-5'>HarmonyOS</b> <b class='flag-5'>5</b>】鸿蒙中进度条的使用<b class='flag-5'>详解</b>

    HarmonyOS 5】鸿蒙星闪NearLink详解

    HarmonyOS 5】鸿蒙星闪NearLink详解 ##鸿蒙开发能力 ##HarmonyOS SDK应用服务##鸿蒙金融类应用 (金融理财# 一、前言 鸿蒙星闪NearLink K
    的头像 发表于 07-11 18:24 1481次阅读
    【<b class='flag-5'>HarmonyOS</b> <b class='flag-5'>5</b>】鸿蒙星闪NearLink<b class='flag-5'>详解</b>

    HarmonyOS 5】鸿蒙mPaaS详解

    HarmonyOS 5】鸿蒙mPaaS详解 ##鸿蒙开发能力 ##HarmonyOS SDK应用服务##鸿蒙金融类应用 (金融理财# 一、mPaaS是什么? mPaaS 是 Mobi
    的头像 发表于 07-11 18:23 659次阅读
    【<b class='flag-5'>HarmonyOS</b> <b class='flag-5'>5</b>】鸿蒙mPaaS<b class='flag-5'>详解</b>

    HarmonyOS 5】金融应用开发鸿蒙组件实践

    HarmonyOS 5】金融应用开发鸿蒙组件实践 ##鸿蒙开发能力 ##HarmonyOS SDK应用服务##鸿蒙金融类应用 (金融理财# 一、鸿蒙生态观察 2024 年 1 月 18 日: 发布
    的头像 发表于 07-11 18:20 743次阅读
    【<b class='flag-5'>HarmonyOS</b> <b class='flag-5'>5</b>】金融应用开发鸿蒙组件实践

    HarmonyOS 5】鸿蒙中的UIAbility详解(二)

    HarmonyOS 5】鸿蒙中的UIAbility详解(二) ##鸿蒙开发能力 ##HarmonyOS SDK应用服务##鸿蒙金融类应用 (金融理财# 一、前言 今天我们继续深入讲解
    的头像 发表于 07-11 18:17 680次阅读
    【<b class='flag-5'>HarmonyOS</b> <b class='flag-5'>5</b>】鸿蒙中的UIAbility<b class='flag-5'>详解</b>(二)

    HarmonyOS 5 入门系列 】鸿蒙HarmonyOS示例项目讲解

    HarmonyOS 5 入门系列 】鸿蒙HarmonyOS示例项目讲解 ##鸿蒙开发能力 ##HarmonyOS SDK应用服务##鸿蒙金融类应用 (金融理财# 一、前言:移动开发
    的头像 发表于 07-07 11:57 794次阅读
    【 <b class='flag-5'>HarmonyOS</b> <b class='flag-5'>5</b> 入门系列 】鸿蒙<b class='flag-5'>HarmonyOS</b>示例项目讲解

    鸿蒙中Stage模型与FA模型详解

    HarmonyOS 5】鸿蒙中Stage模型与FA模型详解 ##鸿蒙开发能力 ##HarmonyOS SDK应用服务##鸿蒙金融类应用 (金融理财# 一、前言 在
    的头像 发表于 07-07 11:50 618次阅读

    HarmonyOS 5】应用更新功能详解

    关键词:#HarmonyOS SDK应用服务、#Appgallery connect、#应用更新 在应用开发场景中,功能迭代与调整是常态。为确保用户使用体验不受影响,应用内更新弹窗提示是兼顾稳定性
    发表于 06-22 18:44

    HarmonyOS 5】桌面快捷方式功能实现详解

    HarmonyOS 5】桌面快捷方式功能实现详解 ##鸿蒙开发能力 ##HarmonyOS SDK应用服务##鸿蒙金融类应用 (金融理财# 一、前言 在移动应用开发中,如何让用户快速
    的头像 发表于 06-21 16:42 1775次阅读
    【<b class='flag-5'>HarmonyOS</b> <b class='flag-5'>5</b>】桌面快捷方式功能实现<b class='flag-5'>详解</b>

    HarmonyOS 5】VisionKit人脸活体检测详解

    HarmonyOS 5】VisionKit人脸活体检测详解 ##鸿蒙开发能力 ##HarmonyOS SDK应用服务##鸿蒙金融类应用 (金融理财# 一、VisionKit人脸活体
    的头像 发表于 06-21 11:52 629次阅读
    【<b class='flag-5'>HarmonyOS</b> <b class='flag-5'>5</b>】VisionKit人脸活体检测<b class='flag-5'>详解</b>

    HarmonyOS 5】鸿蒙中的UIAbility详解(三)

    HarmonyOS 5】鸿蒙中的UIAbility详解(三) ##鸿蒙开发能力 ##HarmonyOS SDK应用服务##鸿蒙金融类应用 (金融理财# 一、前言 本文是鸿蒙中的UIA
    的头像 发表于 06-14 22:32 472次阅读

    HarmonyOS 5】鸿蒙CodeGenie AI辅助编程工具详解

    HarmonyOS 5】鸿蒙CodeGenie AI辅助编程工具详解 一、前言 1、CodeGenie是什么?CodeGenie (代码精灵)作为鸿蒙DevEco IDE自带的AI辅助编码工具
    发表于 06-11 16:34

    HarmonyOS5云服务技术分享--认证文档问题

    各位开发者朋友好!本文将详细讲解如何基于HarmonyOS ArkTS框架集成华为AppGallery Connect(AGC)认证服务,涵盖从项目创建到SDK集成全流程。无论您是首次接入AGC服务
    发表于 05-22 13:20