2026/4/15 17:24:16
网站建设
项目流程
开发电子商务网站和开发新闻类网站什么异同,管理咨询公司是做什么,做视频网站玩什么配置,怎么创建微信小程序店铺为了增强状态管理框架对状态变量变化的监听能力#xff0c;开发者可以使用Monitor装饰器对状态变量进行监听。
Monitor提供了对V2状态变量的监听。在阅读本文档前#xff0c;建议提前阅读#xff1a;ComponentV2#xff0c;ObservedV2和Trace#xff0c;Local。
说明
M…为了增强状态管理框架对状态变量变化的监听能力开发者可以使用Monitor装饰器对状态变量进行监听。Monitor提供了对V2状态变量的监听。在阅读本文档前建议提前阅读ComponentV2ObservedV2和TraceLocal。说明Monitor装饰器从API version 12开始支持。从API version 12开始该装饰器支持在元服务中使用。概述Monitor装饰器用于监听状态变量修改使得状态变量具有深度监听的能力Monitor装饰器支持在ComponentV2装饰的自定义组件中使用未被状态变量装饰器Local、Param、Provider、Consumer、Computed装饰的变量无法被Monitor监听到变化。Monitor装饰器支持在类中与ObservedV2、Trace配合使用不允许在未被ObservedV2装饰的类中使用Monitor装饰器。未被Trace装饰的属性无法被Monitor监听到变化。当观测的属性变化时Monitor装饰器定义的回调方法将被调用。判断属性是否变化使用的是严格相等当严格相等判断的结果是false即不相等的情况下就会触发Monitor的回调。当在一次事件中多次改变同一个属性时将会使用初始值和最终值进行比较以判断是否变化。单个Monitor装饰器能够同时监听多个属性的变化当这些属性在一次事件中共同变化时只会触发一次Monitor的回调方法。Monitor装饰器具有深度监听的能力能够监听嵌套类、多维数组、对象数组中指定项的变化。对于嵌套类、对象数组中成员属性变化的监听要求该类被ObservedV2装饰且该属性被Trace装饰。当Monitor监听整个数组时更改数组的某一项不会被监听到注意Monitor可以监听数组中某一项的变化。无法监听内置类型Array、Map、Date、Set的API调用引起的变化。在继承类场景中可以在父子组件中对同一个属性分别定义Monitor进行监听当属性变化时父子组件中定义的Monitor回调均会被调用。和Watch装饰器类似开发者需要自己定义回调函数区别在于Watch装饰器将函数名作为参数而Monitor直接装饰回调函数。Monitor与Watch的对比可以查看Monitor与Watch的对比。状态管理V1版本Watch装饰器的局限性现有状态管理V1版本可以实现对对象、数组中某一单个属性或数组项变化的监听但无法获取变化之前的值。例子参考状态管理V1版本Watch装饰器的局限性代码示例装饰器说明Monitor属性装饰器说明装饰器参数字符串类型的对象属性名。可同时监听多个对象属性每个属性以逗号隔开例如Monitor(prop1, prop2)。可监听深层的属性变化如多维数组中的某一个元素嵌套对象或对象数组中的某一个属性。详见监听变化。装饰对象Monitor装饰成员方法。当监听的属性发生变化时会触发该回调方法。该回调方法以IMonitor类型的变量作为参数开发者可以从该参数中获取变化前后的相关信息。举例如下Entry ComponentV2 struct Index { Local info: Info new Info(Tom, 25); Monitor(info) infoChange(monitor: IMonitor) { hilog.info(0xFF00, testTag, %{public}s, info change); } Monitor(info.name) infoPropertyChange(monitor: IMonitor) { let lastValue: string monitor.value()?.before as string; let curValue: string monitor.value()?.now as string; hilog.info(0xFF00, testTag, lastValue{lastValue}, currentValue{curValue}, info name change); } // 同时监听状态变量age和非状态变量name Monitor(age, name) onPropertyChange(monitor: IMonitor) { monitor.dirty.forEach((path: string) { hilog.info(0xFF00, testTag, %{public}s, property path:${path} change from ${monitor.value(path)?.before} to ${monitor.value(path)?.now}); }) } } build() { Column() { Text(name: ${this.info.name}, age: ${this.info.age}) Button(change info) .onClick(() { this.info new Info(Lucy, 18); // 能够监听到 }) Button(change info.name) .onClick(() { this.info.name Jack; // 监听不到 }) } } }接口说明IMonitor类型和IMonitorValueT类型的接口说明参考API文档状态变量变化监听。监听变化例子参考状态管理V1版本Watch装饰器的局限性代码示例在ComponentV2装饰的自定义组件中使用Monitor使用Monitor监听的状态变量发生变化时会触发Monitor的回调方法。Monitor监听的变量需要被Local、Param、Provider、Consumer、Computed装饰未被状态变量装饰器装饰的变量在变化时无法被监听。Monitor可以同时监听多个状态变量这些变量名之间用,隔开。Monitor监听的状态变量为类对象时仅能监听对象整体的变化。监听类属性的变化需要类属性被Trace装饰。在ObservedV2装饰的类中使用Monitor使用Monitor监听的属性发生变化时会触发Monitor的回调方法。Monitor监听的对象属性需要被Trace装饰未被Trace装饰的属性的变化无法被监听。Monitor可以同时监听多个属性这些属性之间用,隔开。Monitor可以监听深层属性的变化该深层属性需要被Trace装饰。在继承类场景下可以在继承链中对同一个属性进行多次监听。通用监听能力Monitor还有一些通用的监听能力。Monitor支持对数组中的项进行监听包括多维数组对象数组。Monitor无法监听内置类型Array、Map、Date、Set的API调用引起的变化。当Monitor监听数组整体时只能观测到数组整体的赋值。可以通过监听数组的长度变化来判断数组是否有插入、删除等变化。当前仅支持使用.的方式表达深层属性、数组项的监听。Monitor监听对象中属性时如果对象整体改变但监听的属性不变时不触发该属性的Monitor回调。在一次事件中多次改变被Monitor监听的属性以最后一次修改为准。使用限制例子参考状态管理V1版本Watch装饰器的局限性代码示例使用Monitor需要注意如下限制条件不建议在一个类中对同一个属性进行多次Monitor的监听。当一个类中存在对一个属性的多次监听时只有最后一个定义的监听方法会生效。当Monitor传入多个路径参数时以参数的全拼接结果判断是否重复监听。全拼接时会在参数间加空格以区分不同参数。例如ab, c的全拼接结果为ab ca, bc的全拼接结果为a bc二者全拼接不相等。以下示例中Monitor 1、Monitor 2与Monitor 3都监听了name属性的变化。由于Monitor 2与Monitor 3的入参全拼接相等都为name position因此Monitor 2不生效仅Monitor 3生效。当name属性变化时将同时触发onNameAgeChange与onNamePositionChangeDuplicate方法。但请注意Monitor 2与Monitor 3的写法仍然被视作在一个类中对同一个属性进行多次Monitor的监听这是不建议的。Monitor的参数需要为监听属性名的字符串仅可以使用字符串字面量、const常量、enum枚举值作为参数。如果使用变量作为参数仅会监听Monitor初始化时变量值所对应的属性。当更改变量时Monitor无法实时改变监听的属性即Monitor监听的目标属性从初始化时便已经确定无法动态更改。不建议开发者使用变量作为Monitor的参数进行初始化。建议开发者避免在Monitor中再次更改被监听的属性这会导致无限循环。Monitor与Watch对比Monitor与Watch的用法、功能对比如下用法WatchMonitor参数回调方法名。监听状态变量名、属性名。监听目标数只能监听单个状态变量。能同时监听多个状态变量。监听能力跟随状态变量观察能力一层。跟随状态变量观察能力深层。能否获取变化前的值不能获取变化前的值。能获取变化前的值。监听条件监听对象为状态变量。监听对象为状态变量或为Trace装饰的类成员属性。使用限制仅能在Component装饰的自定义组件中使用。能在ComponentV2装饰的自定义组件中使用也能在ObservedV2装饰的类中使用。使用场景例子参考状态管理V1版本Watch装饰器的局限性代码示例监听深层属性变化Monitor可以监听深层属性的变化并能够根据更改前后的值做分类处理。常见问题例子参考状态管理V1版本Watch装饰器的局限性代码示例自定义组件中Monitor对变量监听的生效及失效时间当Monitor定义在ComponentV2装饰的自定义组件中时Monitor会在状态变量初始化完成之后生效并在组件销毁时失效。类中Monitor对变量监听的生效及失效时间当Monitor定义在ObservedV2装饰的类中时Monitor会在类的实例创建完成后生效在类的实例销毁时失效。Monitor会在类的实例创建完成后生效这个时机晚于类的constructor早于自定义组件的aboutToAppear。类中定义的Monitor随着类的销毁失效。而由于类的实际销毁释放依赖于垃圾回收机制因此会出现即使所在自定义组件已经销毁类却还未及时销毁导致类中定义的Monitor仍在监听变化的情况。借助垃圾回收机制去取消Monitor的监听是不稳定的开发者可以采用以下两种方式去管理Monitor的失效时间1、将Monitor定义在自定义组件中。由于自定义组件在销毁时状态管理框架会手动取消Monitor的监听因此在自定义组件调用完aboutToDisappear尽管自定义组件的数据不一定已经被释放但Monitor回调已不会再被触发。2、主动置空监听的对象。当自定义组件即将销毁时主动置空Monitor的监听目标这样Monitor无法再监听原监听目标的变化达到取消Monitor监听的效果。举例如下aboutToDisappear(): void { hilog.info(0xFF00, testTag, %{public}s, Child aboutToDisappear, this.infoWrapper.info?.age); this.infoWrapper.info undefined; // 使InfoWrapper对info.age的监听失效 }正确设置Monitor入参由于Monitor无法对入参做编译时校验当前存在以下写法不符合Monitor监听条件但Monitor仍会触发的情况。开发者应当正确传入Monitor入参不传入非状态变量避免造成功能异常或行为表现不符合预期。无法监听变量从可访问变为不可访问和从不可访问变为可访问Monitor仅会保存变量可访问时的值当状态变量变为不可访问的状态时并不会记录其值的变化。即不能监听属性从undefined | null变为正常值也不能监听属性从正常值变为undefined | null。从API version 20开始如果需要监听可访问到不可访问和不可访问到可访问的状态变化可以使用addMonitor。