1# ArkUI子系统Changelog 2 3## cl.arkui.1 @Component、@ComponentV2自定义组件冻结变更 4 5**访问级别** 6 7公开接口 8 9**变更原因** 10 11@Component、@ComponentV2 开启组件冻结时,如果解冻组件,会从设置组件冻结标记的父组件开始解冻,然后解冻子组件,但解冻子组件时会解冻子组件的非屏上节点, 12 13为了确保组件冻结对性能的提升,需要修改组件冻结的解冻范围,只解冻子组件的屏上节点。 14 15**变更影响** 16 17该变更为不兼容变更。 18 19运行如下示例代码: 20 21```ts 22// index.ets 23import router from '@ohos.router'; 24 25@Component 26struct ChildOfParamComponent { 27 @Prop @Watch('onChange') child_val: number; 28 29 onChange() { 30 console.log(`Appmonitor ChildOfParamComponent: child_val changed:${this.child_val}`); 31 } 32 33 build() { 34 Column() { 35 Text(`Child Param: ${this.child_val}`); 36 } 37 } 38} 39 40@Component 41struct ParamComponent { 42 @Prop @Watch('onChange') paramVal: number; 43 44 onChange() { 45 console.log(`Appmonitor ParamComponent: paramVal changed:${this.paramVal}`); 46 } 47 48 build() { 49 Column() { 50 Text(`val: ${this.paramVal}`) 51 ChildOfParamComponent({child_val: this.paramVal}); 52 } 53 } 54} 55 56@Component 57struct DelayComponent { 58 @Prop @Watch('onChange') delayVal: number; 59 60 onChange() { 61 console.log(`Appmonitor ParamComponent: delayVal changed:${this.delayVal}`); 62 } 63 64 build() { 65 Column() { 66 Text(`Delay Param: ${this.delayVal}`); 67 } 68 } 69} 70 71@Entry 72@Component ({freezeWhenInactive: true}) 73struct TabsComponent { 74 private controller: TabsController = new TabsController(); 75 @State @Watch('onChange') tabState: number = 47; 76 77 onChange() { 78 console.log(`Appmonitor TabsComponent: tabState changed:${this.tabState}`); 79 } 80 81 build() { 82 Column({space: 10}) { 83 Button(`Incr state ${this.tabState}`) 84 .fontSize(25) 85 .onClick(() => { 86 console.log('Button increment state value'); 87 this.tabState = this.tabState + 1; 88 }) 89 90 Tabs({ barPosition: BarPosition.Start, index: 0, controller: this.controller}) { 91 TabContent() { 92 ParamComponent({paramVal: this.tabState}); 93 }.tabBar('Update') 94 TabContent() { 95 DelayComponent({delayVal: this.tabState}); 96 }.tabBar('DelayUpdate') 97 } 98 .vertical(false) 99 .scrollable(true) 100 .barMode(BarMode.Fixed) 101 .barWidth(400).barHeight(150).animationDuration(400) 102 .width('100%') 103 .height(200) 104 .backgroundColor(0xF5F5F5) 105 106 Button('Next Page') 107 .onClick(() => { 108 router.pushUrl({ 109 url: 'pages/Page2' 110 }); 111 }) 112 } 113 } 114} 115``` 116 117```ts 118// Page2.ets 119import router from '@ohos.router'; 120 121@Entry 122@Component 123struct Second { 124 build() { 125 Column() { 126 Button() { 127 Text('Back') 128 .fontSize(50) 129 .fontWeight(FontWeight.Bold) 130 } 131 .margin({ 132 top: 40 133 }) 134 .onClick(() => { 135 router.back(); 136 }) 137 } 138 .width('100%') 139 .height('100%') 140 } 141} 142``` 143 144父组件TabsComponent开启了组件冻结,点击DelayUpdate标签,之后点击Button:Next Page进入另一个页面,然后返回,标签落在DelayUpdate,点击Button:Incr state,查看log,搜索'Appmonitor'。 145 146变更前:发现有4条打印,除了DelayUpdate标签的打印外,还有Update标签中节点的打印,查看trace,可以看到,Update标签未被选中,其子组件ParamComponent也不在屏上,但是ParamComponent组件进行了刷新,说明父组件解冻时会解冻其所有的子组件。 147 148 149 150变更后:只有2条打印,不再有Update标签中节点的打印,查看trace,只有选中的DelayUpdate标签中的节点被刷新,只有子组件的屏上节点被解冻,非屏上节点不会再被解冻。 151 152 153 154**起始API Level** 155 156@Component :API 11 157 158@ComponentV2:API 12 159 160**变更发生版本** 161 162从OpenHarmony SDK 5.1.0.42开始。 163 164**变更的接口/组件** 165 166@Component的freezeWhenIactive接口 167 168@ComponentV2的freezeWhenIncative接口 169 170**适配指导** 171 172默认行为变更,当开发者开启组件冻结功能之后,从其他界面返回到开启组件冻结功能的界面时,现在不会解锁子组件的屏外节点。 173 174如果开发者希望非屏上的节点也能触发@Watch回调或者@Monitor的回调,那么需要去掉示例代码中的freezeWhenInactive: true,或者将冻结开关设置为freezeWhenInactive: false。