@Track
- @Track概述
- 使用案例
- 使用条件
@Track概述
- @Track是class对象的属性装饰器。当一个class对象是状态变量时(也就是使用@State修饰时),@Track装饰的属性发生变化,只会触发该属性关联的UI更新;而未被标记的属性不能在UI中使用(这句话的意思是在一个class中,如果有@Track的话,只有@Track修饰的变量可以在UI中使用,别的普通属性不能在UI中使用,详见下文使用条件章节)。
- 注意当class对象中没有一个属性被标记@Track,行为与原先保持不变
使用案例
如下代码:
LogTrack
的str1和str2变量都用@Track修饰。LogNotTrack
的str1和str2没有使用@Track修饰。- 提供了
isRender
方法来监听变量的变化
class LogTrack {@Track str1: string;@Track str2: string;constructor(str1: string) {this.str1 = str1;this.str2 = 'World';}
}class LogNotTrack {str1: string;str2: string;constructor(str1: string) {this.str1 = str1;this.str2 = '世界';}
}@Entry
@Component
struct AddLog {@State logTrack: LogTrack = new LogTrack('Hello');@State logNotTrack: LogNotTrack = new LogNotTrack('你好');isRender(index: number) {console.log(`Text ${index} is rendered`);return 50;}build() {Row() {Column() {Text(this.logTrack.str1) // UINode1.fontSize(this.isRender(1)).fontWeight(FontWeight.Bold)Text(this.logTrack.str2) // UINode2.fontSize(this.isRender(2)).fontWeight(FontWeight.Bold)Button('change logTrack.str1').onClick(() => {this.logTrack.str1 = 'Bye';}).backgroundColor(Color.Red)Text(this.logNotTrack.str1) // UINode3.fontSize(this.isRender(3)).fontWeight(FontWeight.Bold)Text(this.logNotTrack.str2) // UINode4.fontSize(this.isRender(4)).fontWeight(FontWeight.Bold)Button('change logNotTrack.str1').onClick(() => {this.logNotTrack.str1 = '再见';})}.width('100%')}.height('100%')}
}
- 初始化运行效果:
- 当点击红色按钮时,类
LogTrack
中的属性均被@Track
装饰器装饰,此时UINode1
刷新,UINode2
不刷新,只有一条日志输出,避免了冗余刷新。
- 当点击蓝色按钮时,类
LogNotTrack
中的属性均未被@Track装饰器装饰,此时UINode3、UINode4均会刷新,有两条日志输出,存在冗余刷新。
使用条件
- 不能在UI中使用非@Track装饰的属性,包括不能绑定在组件上、不能用于初始化子组件,错误的使用将导致
JSCrash
;可以在非UI中使用非@Track装饰的属性,如事件回调函数中、生命周期函数中等。
第一句是什么意思呢?比如我们将LogTrack
的str2的属性@Track
去掉的话,如图
再次运行,app会崩溃,报如下错误:意思是str2没有使用@Track标签装饰,不能在UI中使用
xxx.ee E [nodict]Error type:Error
06-13 10:23:47.814 22686-22686 C01305/Appkit com.xxxxx.ee E [nodict]Error name:Error
06-13 10:23:47.814 22686-22686 C01305/Appkit com.xxxxx.ee E [nodict]Error message:Illegal usage of not @Track'ed property 'str2' on UI!
06-13 10:23:47.814 22686-22686 C01305/Appkit com.xxxxx.ee E [nodict]Stacktrace:
06-13 10:23:47.814 22686-22686 C01305/Appkit com.xxxxx.ee E [nodict]SourceMap is not initialized yet
06-13 10:23:47.814 22686-22686 C01305/Appkit com.xxxxx.ee E [nodict] at onOptimisedObjectPropertyRead (/usr1/hmos_for_system/src/increment/sourcecode/foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/engine/stateMgmt.js:4039:4039)
06-13 10:23:47.814 22686-22686 C01305/Appkit com.xxxxx.ee E [nodict] at get (/usr1/hmos_for_system/src/increment/sourcecode/foundation/arkui/ace_engine/frameworks/bridge/declarative_frontend/engine/stateMgmt.js:2042:2042)
06-13 10:23:47.814 22686-22686 C01305/Appkit com.xxxxx.ee E [nodict] at anonymous (entry/src/main/ets/pages/tztZFHeadPage.ets:86:25)
- 建议开发者不要混用包含@Track的class对象和不包含@Track的class对象,如联合类型中、类继承中等。
参考资料:
@Track装饰器:class对象属性级更新