• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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![freeze_before](figures/freeze_before.png)
149
150变更后:只有2条打印,不再有Update标签中节点的打印,查看trace,只有选中的DelayUpdate标签中的节点被刷新,只有子组件的屏上节点被解冻,非屏上节点不会再被解冻。
151
152![freeze_after](figures/freeze_after.png)
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。