@ObservedV2 和 @Trace: 类属性变化观测@ObservedV2装饰器和@Trace装饰器:类属性变化观测状态管理V1 版本无法实现对嵌套类对象属性变化的直接观察,通常需要使用 @ObjectLink 装饰器和自定义组件来实现观察,但当嵌套层级较深时,代码会变得是否复杂,易用性差。@ObservedV2 和 @Trace 提供了对嵌套类对象属性变化的直接观察能力。装饰器装饰器参数装饰的类型@ObservedV2无class@Trace无class 中成员属性,属性的类型可为基本数据类型和 Array、Date、Map、Set 等,不支持 Function 类型@ObservedV2 用于装饰类,@Trace 用于装饰类中的属性,使得被装饰的类和属性具有深度观测的能力:@ObservedV2 和 @Trace 需配合使用,单独使用 @ObservedV2 或 @Trace 没有任何作用被 @Trace 装饰的属性的值变化时,仅会通知与其关联的组件进行刷新;未被 @Trace 装饰的属性值的变化无法触发 UI 刷新使用 @ObservedV2 和 @Trace 装饰的类,需通过 new 实例化后,才具备被观测变化的能力在继承类中,父类或子类中的属性被 @Trace 装饰,且该属性所在的类被 @ObservedV2 装饰时,才具有 UI 刷新的能力在嵌套类中,嵌套类中的属性被 @Trace 装饰且嵌套类被 @Observed 装饰时,才具有触发 UI 刷新的能力@Trace 装饰 Array、Date、Map、Set 的内置类型时,可观测到集合内置类的变化在 @ComponentV2 自定义组件中,被 @ObservedV2 与 @Trace 装饰的变量具有深度观察能力,但对对象整体赋值时,UI 不会自动刷新,状态变量对象需被 @Local 装饰,才可观测对象本身的变化使用限制@ObservedV2 和 @Trace 仅能装饰 class 和属性,不能用在自定义组件中使用ObservedV2/@Trace 有自己独立的观测能力,不仅可在 @ComponentV2 中使用,也可以独立在 @Component 中使用,但不可与 V1 状态管理装饰器混合使用,编译时报错继承自 @ObservedV2 的类无法和 @State 等 V1 的装饰器混合使用,运行时报错@ObservedV2 的类实例无法直接使用 JSON.parse 反序列化获得 (直接使用 JSON.parse 反序列化获得的对象无法观察属性变化,需使用makeObserved方法转换)使用场景嵌套类场景V2 的观测能力绑定在发生变化的属性所在的那个类上,而不是绑定在访问路径的根对象上。嵌套类,只要内层 class 本身被 @ObservedV2 装饰、其属性被 @Trace 装饰,那么无论外层对象是否可观测,该属性的变化都能被追踪到,可触发 UI 刷新。即外层的类可以不被 @ObservedV2 和 @Trace 装饰,但若要观察内层 class 的整体赋值 (outer.inner = new inner()),则需用 @Trace 装饰外层字段本身,才能观测并触发 UI 刷新。// 嵌套类必须被 @ObservedV2 和 @Trace 装饰,才能触发 UI@ObservedV2classUser{@Traceage:number=10;}// 外层的类可以不被 @ObservedV2 和 @Trace 装饰classLogin{user:User=newUser();}@Entry@ComponentV2exportstruct MainPage{// login 的嵌套类 User 被 @ObserveV2 装饰,不可用 @State 等 V1 的装饰器// 即使 login 没有被 @Local 装饰,其 age 属性的改变也会触发 UI 刷新@Locallogin:Login=newLogin();build(){Column({space:20}){Button('change age: '+this.login.user.age).onClick(()={this.login.user.age++})}.width('100%')}}继承类场景@Trace 支持在类的继承场景中使用,无论是在基类还是继承类中,只有被 @Trace 装饰的属性才具有被观测变化的能力。@ObservedV2classUser{// 被 @Trace 装饰,值的变化可触发 UI 刷新@Traceage:number=10;}@ObservedV2classVipextendsUser{// 被 @Trace 装饰,值的变化可触发 UI 刷新@Tracelevel:number=1;// 未被 @Trace 装饰,不会触发 UI 刷新date:string='';}@Entry@ComponentV2exportstruct MainPage{@Localvip:Vip=newVip();build(){Column({space:20}){Button('change age: '+this.vip.age).onClick(()={this.vip.age++})Button('change level: '+this.vip.level).onClick(()={this.vip.level++})}.width('100%')}}@Trace 装饰对象数组@Trace 装饰 Array、Date、Map、Set 的内置类型时,可观测到集合内置类的变化@ObservedV2classUser{// 被 @Trace 装饰,值的变化可触发 UI 刷新@Traceage:number;constructor(age:number){this.age=age;}}@Entry@ComponentV2exportstruct MainPage{// 数组的 userList 的内置类 User 的 age 属性被 @Trace 装饰,其变化可触发 UI 刷新userList:ArrayUser=[newUser(10)];build(){Column({space:20}){Button('change age: '+this.userList[0].age).onClick(()={this.userList[0].age++})}.width('100%')}}@ObservedV2 装饰对象的序列化与反序列化@ObservedV2 装饰的对象序列化后会为 @Trace 装饰的属性添加__ob_前缀@ObservedV2classInfo{@Tracename:string='Tom';@Traceage:number=24;}letrealInfo:Info=newInfo();letjsonResult:string=JSON.stringify(realInfo);// '{"__ob_name":"Tom","__ob_age":24}'由于 @ObservedV2 装饰的对象序列化后会为 @Trace 装饰的属性添加__ob_前缀,再通过 JSON.parse 对其反序列化,将失去观察能力,且得到的并非原对象实例,不能直接通过 as 强制类型转换成原对象。@ObservedV2classInfo{@Tracename:string='Tom';@Traceage:number=24;}letjsonResult:string=JSON.stringify(newInfo());// '{"__ob_name":"Tom","__ob_age":24}'letparseInfo:Info=JSON.parse(jsonResult);// parseInfo 实际并不是 Info 的实例letname:string=parseInfo.name;// parseInfo 的属性名已经变为了 __ob_name,parseInfo.name 为 undefined;在传递 (Router 路由传参、Navigation 组件传参、跨线程通信) 和存储 (Preferences 持久化) 对象时,都会经历 “序列化+反序列化” 的过程如:通过router.pushUrl()参数对象时,参数对象会被序列化后传递,目标页通过router.getParams()拿到的是反序列化后重新生成的对象。// FirstPge 跳转,并传递 @ObservedV2 实例this.getUIContext().getRouter().pushUrl({url:'pages/secondPage',params:this.info;})// secondPage 接收参数// 错误的方式!// 通过 router 传递 @ObservedV2 对象,其在获取后属性名已经改变了,拼接了 __ob_ 前缀,无法通过 as 直接强制转换// this.params 的属性名为 __ob_name,非原始 Info 的实例,不可观测this.params=this.getUIContext().getRouter().getParams()asInfo;为了解决上述问题,可配合三方库 class-transformer 实现反序列,对象的属性名不变,且可观测。安装 class-transformerohpm installclass-transformer【示例】import{plainToInstance}from'class-transformer';// 导入三方库@ObservedV2classInfo{@Tracename:string='Assassin';@Traceage:number=28;}@Entry@ComponentV2exportstruct MainPage{jsonStr:string="{\"name\":\"Assassin\",\"age\":28}";// 通过反序列得到的对象实例 parseInfo,无法观测@LocalparseInfo:Info=JSON.parse(this.jsonStr);// 三方库 class-transformer 实现的反序列化实例,可以被观测@LocaltransformedParseInfo:Info=plainToInstance(Info,this.parseInfo);// 将 Info 序列化后,再返序列化得到的对象@LocalinfoStr:string=JSON.stringify(newInfo());@Localinfo:Info=JSON.parse(this.infoStr)asInfo;// 三方库 class-transformer 将 info 转为可被观察的对象@LocaltransformedInfo:Info=plainToInstance(Info,this.info);aboutToAppear():void{// 接收 router 参数,需先将接收的参数序列化letparamStr:string=JSON.stringify(this.getUIContext().getRouter().getParams());// 反序列化后,通过 plainToInstance 转为可被观察的对象letparams:Info=plainToInstance(Info,JSON.parse(paramStr));}build()
企业数字化 ERP 产品动态
相关推荐
mysql主从复制和读写分离部署手记 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/15 0:53:41
从verts到.obj:WiLoR输出数据格式全解读,AR手部交互与3D资产开发实战 【免费下载链接】WiLoR WiLoR: End-to-end 3D hand localization and reconstruction in-the-wild 项目地址: https://gitcode.com/gh_mirrors/wi/WiLoR 点击查看 免费下载 WiLoR 是一个端到端的 3D 手部定位与重建模型(CVPR 2025)ÿ… · 2026/11/3 1:41:19
Sunshine 游戏串流主机一次跑通:装好、连通首条串流并调好常见参数 Sunshine 游戏串流主机一次跑通:装好、连通首条串流并调好常见参数 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine
Sunshine 是一个自托管游戏串流主机:装在… · 2026/11/15 1:07:25
临沂电工证报名用材料 怎么报名才不会被坑 临沂电工证报名用材料 怎么报名才不会被坑 你是不是正愁着不知道去哪报名临沂电工证,怕被中介骗钱?别急,今天我就用最接地气的方式,告诉你 临沂电工证报名用材料 到底需要啥, 怎么报名… · 2026/11/15 18:46:40
工地太忙根本没时间复习考试?想考电工证用什么软件+电子证书攻略来了 工地太忙根本没时间复习考试?想考电工证用什么软件+电子证书攻略来了 工地太忙根本没时间复习考试,很多人一提考证就犯愁,特别是像电工证这种实操性强、考试内容又多的特种作业操作证,更是让人头疼。但你知道吗?现在市面上已经有不少 软件… · 2026/11/15 18:46:40
外线电工作业有哪些报名门槛低吗电子证书怎么查 外线电工作业有哪些报名门槛低吗电子证书怎么查 你是不是学历不高,担心自己根本报不上名?别急,外线电工作业虽然听起来门槛高,但其实只要符合基本条件, 电子证书… · 2026/11/15 18:46:40
数据电工证报考保姆级教程:怕考不过白交培训费?看完这篇不踩坑 数据电工证报考保姆级教程:怕考不过白交培训费?看完这篇不踩坑 怕考不过白交培训费?别急,数据电工证不是随便就能拿下来的,但也不是你想象中那么难。关键是选对培训机构、掌握备考方法、熟悉考试流程。本文从周口学员的真实经历出发,带你一步步了解数据… · 2026/11/15 18:46:40
低高压电工作业考试多少钱?外省证书能不能转过来? 低高压电工作业考试多少钱?外省证书能不能转过来? 之前考的证在外省能不能转过来?这几乎是每个打算报考低压、高压电工作业考试的人最关心的问题。而且, 多少钱… · 2026/11/15 18:46:40
青岛城阳区报考电工证多少钱?工地太忙根本没时间复习考试怎么办? 青岛城阳区报考电工证多少钱?工地太忙根本没时间复习考试怎么办? 工地太忙根本没时间复习考试,你是真正在一线干活的电工,每天赶工期、盯进度,哪还有空去刷题?但现实是, 青岛城阳区报考电工证 必须通过考试,不然连上岗都成问题。 多少钱… · 2026/11/15 18:45:40
长春初级电工证怎么考?通过率揭秘全在这里 长春初级电工证怎么考?通过率揭秘全在这里 之前考的证在外省能不能转过来?这几乎是每个想从事电工工作的人都会问的问题。特别是那些在外地打拼多年、手里握着一张“外地电工证”的人,到了长春想继续干这一行,第一反应就是“我的证能用吗?”。今天我们就… · 2026/11/15 0:00:50
国内电工证报考条件与考试时间 低压电工证怎么考?学历不高也能报名,官方报名入口全在这 你是不是经常听说“电工证是入行门槛”,但又担心自己学历不够、经验不足,根本报不了名?别急,今天就带你从零了解【国内电工证】的报考流程、考试内容,还有怎么在 官方报名入口… · 2026/11/15 0:00:50
电工作业时如何断电?电子证书到底能不能全国通用? 电工作业时如何断电?电子证书到底能不能全国通用? 实操考试心里没底怕挂科,特别是电工作业时如何断电这一操作,不仅关系到你能不能拿到证书,更关系到以后能不能顺利上岗。很多人觉得这不过就是“断个电”,但其实这里面的门道可不少,稍有不慎就可能出错… · 2026/11/15 0:00:50
长春初级电工证怎么考?通过率揭秘全在这里 长春初级电工证怎么考?通过率揭秘全在这里 之前考的证在外省能不能转过来?这几乎是每个想从事电工工作的人都会问的问题。特别是那些在外地打拼多年、手里握着一张“外地电工证”的人,到了长春想继续干这一行,第一反应就是“我的证能用吗?”。今天我们就… · 2026/11/15 0:00:50
国内电工证报考条件与考试时间 低压电工证怎么考?学历不高也能报名,官方报名入口全在这 你是不是经常听说“电工证是入行门槛”,但又担心自己学历不够、经验不足,根本报不了名?别急,今天就带你从零了解【国内电工证】的报考流程、考试内容,还有怎么在 官方报名入口… · 2026/11/15 0:00:50
电工作业时如何断电?电子证书到底能不能全国通用? 电工作业时如何断电?电子证书到底能不能全国通用? 实操考试心里没底怕挂科,特别是电工作业时如何断电这一操作,不仅关系到你能不能拿到证书,更关系到以后能不能顺利上岗。很多人觉得这不过就是“断个电”,但其实这里面的门道可不少,稍有不慎就可能出错… · 2026/11/15 0:00:50
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/15 1:51:20
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/15 4:02:19
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/15 3:02:05