鸿蒙应用开发之@State 装饰器详解:从基本类型到 @Observed/@ObjectLink/@Track 嵌套监听
文章目录一、引言二、什么是 State三、监听基本数据类型四、监听对象类型五、监听嵌套对象5.1 Observed5.2 ObjectLink5.4 Track5.5 与 Observed 的区别六、总结对比七、关键要点这是一个使用鸿蒙技术开发的本地原生记账应用非常适合大家用来练手。相关源码已上传至 Github点击此处查看项目。欢迎大家交流、指正也欢迎提交 PR。一、引言在鸿蒙HarmonyOS应用开发中ArkTS 框架提供了一套强大的响应式编程模型。其中State装饰器是实现组件内部状态管理、驱动 UI 自动刷新的核心工具。本文将深入浅出地讲解State的使用方法、监听机制以及最佳实践帮助你快速掌握这一关键特性。二、什么是 StateState是 HarmonyOS ArkTS 框架中用于管理组件内部状态的核心装饰器它实现了数据驱动 UI 的响应式编程。被State修饰的变量变化时依赖该变量的 UI 组件会自动重新渲染保持数据与界面的同步。其底层基于依赖收集和变更通知机制组件渲染时框架会收集State变量的 UI 依赖关系当变量被修改时框架会通知所有依赖方执行最小化更新从而高效地刷新界面。三、监听基本数据类型对于boolean、string、number等基础类型直接赋值即可被框架观察到并触发 UI 刷新。EntryComponentstruct BasicTypeDemo{Statecount:number0;Statename:stringHello;build(){Column({space:20}){Text(Count:${this.count}).fontSize(30)Text(Name:${this.name}).fontSize(30)Button(Increment).onClick((){this.count;// 可观察触发UI刷新})Button(Change Name).onClick((){this.nameArkTS;// 可观察触发UI刷新})}}}运行效果如下四、监听对象类型State可以观察到对象自身的赋值以及属性赋值的变化但需要注意必须通过赋值操作修改对象或其属性直接修改嵌套子属性第二层及以下State无法监测。interfaceIUser{name:stringage:number}EntryComponentstruct ObjectDemo{Stateuser:IUser{name:Alice,age:25};build(){Column({space:20}){Text(Name:${this.user.name}).fontSize(20)Text(Age:${this.user.age}).fontSize(20)Button(Update Age).onClick((){// ✅ 属性赋值可观察this.user.agethis.user.nameBeer})Button(Replace Object).onClick((){// ✅ 整体赋值可观察this.user{name:Bob,age:30};})}}}五、监听嵌套对象示例嵌套对象结构classPet{name:string阿旺;age:number2;}classPerson{name:stringJerry;age:number18;pet:PetnewPet();}EntryComponentstruct NestedDemo{Stateperson:PersonnewPerson();build(){Column({space:20}){Text(name:${this.person.name}).fontSize(20)Text(age:${this.person.age}).fontSize(20)Text(pet name:${this.person.pet.name}).fontSize(20)Text(pet age:${this.person.pet.age}).fontSize(20)Button(改变人的年龄).onClick((){// ✅ 第一层变化State可观察this.person.age})Button(改变宠物的年龄).onClick((){// ❌ 不可观察this.person.pet.age})}}}上述代码中当点击第二个按钮改变宠物的年龄时对this.person.pet.age重新进行了赋值但是页面并没有发生变化。这是因为State只支持一层观察无法递归监听嵌套对象深层属性的变化。对于嵌套对象二层及以下属性的变化必须配合Observed和ObjectLink装饰器。5.1 ObservedObserved是一个类装饰器用于标记一个类为可观察的。当类被Observed装饰后其实例的属性变化可以被框架追踪到即使这些属性是嵌套的深层属性。通常与ObjectLink配合使用解决State无法监听嵌套对象深层变化的限制。5.2 ObjectLinkObjectLink是一个变量装饰器用于在子组件中接收父组件传递过来的Observed装饰类的实例。它会在子组件中建立对父组件数据的引用当被引用的属性发生变化时子组件会自动刷新。当数据结构包含多层嵌套如对象中包含对象、数组等且需要监听深层属性的变化时使用ObservedObjectLink组合是最佳实践。父组件用State持有顶层对象子组件用ObjectLink接收嵌套对象从而实现深度响应式监听。下面使用 Observed ObjectLink对上面的嵌套对象结构进行改造// 使用Observed装饰被嵌套的类ObservedclassPet{name:string阿旺;age:number2;}classPerson{name:stringJerry;age:number18;pet:PetnewPet();}EntryComponentstruct NestedDemo{Stateperson:PersonnewPerson();build(){Column({space:20}){Text(person name:${this.person.name}).fontSize(20)Text(person age:${this.person.age}).fontSize(20)PetComponent({pet:this.person.pet})Button(改变人的年龄).onClick((){this.person.age})Button(改变宠物的年龄).onClick((){// 现在可以观察到嵌套属性的变化this.person.pet.age})}}}Componentstruct PetComponent{ObjectLinkpet:Pet;build(){Column({space:20}){Text(component pet name:${this.pet.name}).fontSize(20)Text(component pet age:${this.pet.age}).fontSize(20)}}}5.4 Track上述代码虽然实现了对深层次数据变化的监听但依然存在问题。为了验证这个问题我们对代码进行如下改造// ...EntryComponentstruct NestedDemo{//...isRender(tag:string):number{console.log(Text${tag}is rendered);return20;}build(){Column({space:20}){Text(person name:${this.person.name}).fontSize(this.isRender(person name))Text(person age:${this.person.age}).fontSize(this.isRender(person age))PetComponent({pet:this.person.pet})Button(改变人的年龄).onClick((){this.person.age})Button(改变宠物的年龄).onClick((){this.person.pet.age})}}}//...添加了isRender(tag: string)方法打开 Log 窗口点击改变人的年龄按钮可以看到问题分析咱们只修改了人的年龄但人名那个文本也被重新渲染了这明显不合适造成了过度渲染。这种过度渲染会带来以下问题性能浪费不必要的UI更新消耗CPU和GPU资源响应延迟大量不必要的渲染操作会降低应用响应速度电池消耗频繁的UI更新会增加设备功耗要想解决这个问题可以使用Track装饰器。Track装饰器是鸿蒙ArkTS框架中用于精细化状态管理的工具它能够精确追踪对象内部特定属性的变化仅在标记的属性发生变更时触发UI更新。这解决了传统状态管理如State中“过度渲染”的问题——传统方式下即使对象只有一个属性变化也会导致整个组件重新渲染造成性能浪费。在类定义中使用Track装饰需要被观察的属性//...classPerson{Trackname:stringJerry;Trackage:number18;Trackpet:PetnewPet();}EntryComponentstruct NestedDemo{//...}//...上面咱们对name、age、pet三个属性都使用Track进行了修饰可能你会疑惑咱们只是修改的age属性的值其他两个为啥也要用Track修饰呢这是是因为未使用Track标记的属性不能在 UI 组件中使用否则会报错。name、pet属性咱们都用在UI组件中使用了为了防止报错所以都用Track进行了修饰。注意可以在非 UI 组件中使用非Track装饰的属性如事件回调函数中、生命周期函数中等。5.5 与 Observed 的区别Observed是类装饰器作用于整个类使类的所有属性都可被观察。Track是属性装饰器作用于类中的具体属性只标记需要被观察的字段。当只需要监听嵌套对象中的某几个属性时使用Track更加轻量和精确避免不必要的性能开销。六、总结对比数据类型监听方式可观察的修改注意事项基本类型number/string/booleanState直接赋值最基础的响应式用法性能最佳对象第一层属性State整体赋值、属性赋值嵌套属性第二层及以下不可观察嵌套对象第二层及以下ObservedObjectLink深层属性变化可观察类需用Observed装饰子组件用ObjectLink接收嵌套对象精确控制Track仅标记的属性变化可观察避免过度渲染提升性能未标记的属性不能在 UI 中使用七、关键要点State变量必须初始化且通过this.xxx value修改支持基本类型和对象及对象第一层属性的变化监听。嵌套对象的深层变化需要Observed/ObjectLink配合实现深度观察父组件用State持有顶层对象子组件用ObjectLink接收嵌套对象。Track装饰器用于精确控制属性观察仅标记的属性变化才触发 UI 更新可有效避免过度渲染问题但未标记Track的属性不能在 UI 中使用否则会导致 JSCrash。

相关新闻

具身智能的定义、特征与原理解析(19)

具身智能的定义、特征与原理解析(19)

前沿技术介绍:AI智能体视觉(TVA,Transformer-based Vision Agent)是依托Transformer架构与“因式智能体”理论所构建的颠覆性工业视觉技术,属于“物理AI” 领域的一种全新技术形态,完成了从“虚拟世界”到“…

2026/10/7 0:34:55 阅读更多 →
Vineyard项目构建与发布:Gradle配置与Android TV应用打包指南

Vineyard项目构建与发布:Gradle配置与Android TV应用打包指南

Vineyard项目构建与发布:Gradle配置与Android TV应用打包指南 【免费下载链接】Vineyard Vine client for Android TV 项目地址: https://gitcode.com/gh_mirrors/vi/Vineyard Vineyard是一款专为Android TV打造的Vine客户端应用,本指南将详细介绍…

2026/10/12 22:17:47 阅读更多 →
具身智能的定义、特征与原理解析(10)

具身智能的定义、特征与原理解析(10)

前沿技术介绍:AI智能体视觉(TVA,Transformer-based Vision Agent)是依托Transformer架构与“因式智能体”理论所构建的颠覆性工业视觉技术,属于“物理AI” 领域的一种全新技术形态,完成了从“虚拟世界”到“…

2026/10/9 15:45:59 阅读更多 →

最新新闻

无人自助拼豆系统开发实战 核心功能实现逻辑与部署上线完整指南

无人自助拼豆系统开发实战 核心功能实现逻辑与部署上线完整指南

无人自助拼豆系统概述 无人自助拼豆系统是一种基于物联网和移动互联网技术的智能设备管理系统,旨在为用户提供便捷的拼豆服务。该系统通常包括用户端、管理后台及硬件设备之间的交互逻辑,能够实现从用户下单到设备操作的全流程自动化。在实际开发中&…

2026/10/14 18:01:22 阅读更多 →
Python操作Neo4j实战:从图数据库基础到Cypher查询优化

Python操作Neo4j实战:从图数据库基础到Cypher查询优化

在Python里折腾过关系型数据库之后,一旦遇到多度关系查询、层级不确定的数据,SQL那一套JOIN写起来真是又臭又长。后来我在实际项目里接触了图数据库,开始用Python操作Neo4j,才算打开了新世界的大门:原来“朋友的朋友的…

2026/10/14 18:01:22 阅读更多 →
MLX90614红外测温实战:从I2C读取到发射率校准的完整指南

MLX90614红外测温实战:从I2C读取到发射率校准的完整指南

简介:基于51单片机和MXL90614红外传感器的非接触式温度测温工程,适合单片机初学者及电子爱好者动手实践。资源围绕传感器信号读取、温度值换算与液晶显示三个核心环节展开,能够帮助学习者快速搭建一个可用的红外测温小系统。压缩包体积仅8KB&…

2026/10/14 18:01:22 阅读更多 →
负空间、视觉双关与尺度对比:qiaomu-mondo-poster-design 的3大构图原理深度剖析

负空间、视觉双关与尺度对比:qiaomu-mondo-poster-design 的3大构图原理深度剖析

AI 技能AI 应用媒体生成 【免费下载链接】qiaomu-mondo-poster-design 一句话生成大师级海报、书籍封面、专辑封面和各类设计作品。无需懂PS、配色或艺术史,AI自动选择最佳风格(基于20位传奇海报设计师)。支持电影海报、读书笔记、公众号封面…

2026/10/14 18:01:22 阅读更多 →
Windows下Elasticsearch安装避坑记录:环境变量、启动报错与IK分词配置

Windows下Elasticsearch安装避坑记录:环境变量、启动报错与IK分词配置

先说个结论:Elasticsearch 在 Linux 上装,熟练之后真的就是解压、改配置、启动三步走;但在 Windows 上装,如果你运气不够好,能从环境变量一路踩到分词插件,每个环节都有惊喜。我这边用的是某台 8GB 内存的 …

2026/10/14 18:01:22 阅读更多 →
数据库与缓存实战指南:从MySQL索引到Redis穿透与雪崩

数据库与缓存实战指南:从MySQL索引到Redis穿透与雪崩

得,直接开始正题。聊到互联网后端,我估计前面两篇已经把HTTP协议、Web框架、接口设计这些基础盘得差不多了,这篇咱们必须得换个频道,聊聊在“学习记录”这个系列里最劝退、也最躲不开的硬骨头——数据库与缓存。你去看各大招聘网站…

2026/10/14 18:00:22 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →