鸿蒙应用开发之@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/7/21 19:32:04 阅读更多 →
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/7/21 17:40:33 阅读更多 →
具身智能的定义、特征与原理解析(10)

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

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

2026/7/21 19:32:05 阅读更多 →

最新新闻

C++ vector模拟实现:从内存管理到现代C++特性的深度解析

C++ vector模拟实现:从内存管理到现代C++特性的深度解析

1. 项目概述:为什么我们要亲手模拟实现vector?在C的世界里,std::vector几乎是每个开发者最早接触、也最频繁使用的容器。它封装了动态数组,提供了自动内存管理、随机访问和高效的尾部增删操作。然而,对于许多开发者来说…

2026/7/22 0:10:31 阅读更多 →
前言《从Harness Engineering 到 Loop Engineering:长程任务Agent原理与实战》

前言《从Harness Engineering 到 Loop Engineering:长程任务Agent原理与实战》

前言:写给每一个未来的 Loop 工程师“你不该再给编程 Agent 写提示词了,你应该设计循环来提示你的 Agent。” —— Peter Steinberger, OpenClaw 创始人为什么写这本书 2026 年中,AI 工程领域正在发生一次安静的革命。 如果说 2022 年 ChatGP…

2026/7/22 0:10:31 阅读更多 →
基于大数分解的困难性而开发的非对称加密算法是 RSA(Rivest–Shamir–Adleman)

基于大数分解的困难性而开发的非对称加密算法是 RSA(Rivest–Shamir–Adleman)

基于大数分解的困难性而开发的非对称加密算法是 RSA(Rivest–Shamir–Adleman)。RSA 的安全性依赖于将一个大合数(通常是两个大素数的乘积)进行因式分解在计算上极为困难这一数学难题。 RC4 是一种对称流密码算法;MD5 …

2026/7/22 0:09:30 阅读更多 →
国密体系(GM/T系列标准)强调自主可控:SM4(对称)、SM2(非对称)、SM3(哈希)、SM9(标识密码)

国密体系(GM/T系列标准)强调自主可控:SM4(对称)、SM2(非对称)、SM3(哈希)、SM9(标识密码)

表格简明概括了三类主流加密算法的核心特征,以下是更系统的对比与补充说明:类别代表算法特点速度典型用途安全性备注对称加密DES(已淘汰)、AES(推荐)、SM4(国密)加解密使用相同密钥&…

2026/7/22 0:09:30 阅读更多 →
结构性设计模式(Structural Design Patterns)是面向对象设计模式中的一类

结构性设计模式(Structural Design Patterns)是面向对象设计模式中的一类

结构性设计模式(Structural Design Patterns)是面向对象设计模式中的一类,主要用于处理类或对象的组合关系,以简化系统结构、提高代码复用性与灵活性。它们关注如何将类和对象组合成更大的结构,同时保持系统的松耦合与…

2026/7/22 0:09:30 阅读更多 →
企业AI知识库的多行业技术实现:数据架构、检索策略与安全设计的差异化实践

企业AI知识库的多行业技术实现:数据架构、检索策略与安全设计的差异化实践

企业AI知识库的多行业技术实现:数据架构、检索策略与安全设计的差异化实践本文从技术架构师视角,深入分析企业AI知识库在金融、医疗、政务、制造、法律、能源、教育、科技八大行业中的技术实现差异,重点探讨数据处理策略、检索优化方案和安全…

2026/7/22 0:09:30 阅读更多 →

日新闻

TI DSP系统配置模块SYSCFG详解:中断机制与主设备优先级配置实战

TI DSP系统配置模块SYSCFG详解:中断机制与主设备优先级配置实战

1. 项目概述与SYSCFG模块的核心价值在嵌入式系统,尤其是像TI C6000系列这样的高性能DSP开发中,我们常常会与芯片手册里那些密密麻麻的寄存器打交道。很多开发者可能更关注算法实现、内存优化或者外设驱动,但对于一个稳定、高效的系统而言&…

2026/7/22 0:00:26 阅读更多 →
微信Server酱:高到达率的应急通知方案实践

微信Server酱:高到达率的应急通知方案实践

1. 为什么我们需要"最次"的通知方案? 在数字化协作环境中,消息通知系统的重要性不言而喻明。但现实情况是,企业级通知方案往往需要复杂的API对接(如企业微信、钉钉、飞书),个人开发者的小项目又经…

2026/7/22 0:00:26 阅读更多 →
甲方要的“简洁“PPT,到底是简洁还是省事?

甲方要的“简洁“PPT,到底是简洁还是省事?

甲方说"简洁一点",乙方听到的是"少做几页"。甲方说"不要太复杂",乙方理解成"别放图表了"。结果交过去,甲方说"我说的简洁不是这个意思"。"简洁"这个词在PPT语境里,是…

2026/7/22 0:00:26 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/21 8:48:31 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/21 5:34:47 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/21 8:25:39 阅读更多 →

月新闻