1# 自定义组件的生命周期
2
3自定义组件的生命周期回调函数用于通知用户该自定义组件的生命周期,这些回调函数是私有的,在运行时由开发框架在特定的时间进行调用,不能从应用程序中手动调用这些回调函数。不要在多个窗口复用同一个自定义组件节点,其生命周期可能会紊乱。
4
5>**说明:**
6>
7>- 本模块首批接口从API version 7开始支持,后续版本的新增接口,采用上角标单独标记接口的起始版本。
8>- 允许在生命周期函数中使用Promise和异步回调函数,比如网络资源获取,定时器设置等。
9
10
11## aboutToAppear
12
13aboutToAppear?(): void
14
15aboutToAppear函数在创建自定义组件的新实例后,在执行其build()函数之前执行。允许在aboutToAppear函数中改变状态变量,更改将在后续执行build()函数中生效。实现自定义布局的自定义组件的aboutToAppear生命周期在布局过程中触发。
16
17**卡片能力:** 从API version 9开始,该接口支持在ArkTS卡片中使用。
18
19**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
20
21**系统能力:** SystemCapability.ArkUI.ArkUI.Full
22
23## onDidBuild<sup>12+</sup>
24
25onDidBuild?(): void
26
27onDidBuild函数在执行自定义组件的build()函数之后执行,开发者可以在这个阶段进行埋点数据上报等不影响实际UI的功能。不建议在onDidBuild函数中更改状态变量、使用animateTo等功能,这可能会导致不稳定的UI表现。
28
29**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
30
31**系统能力:** SystemCapability.ArkUI.ArkUI.Full
32
33## aboutToDisappear
34
35aboutToDisappear?(): void
36
37aboutToDisappear函数在自定义组件析构销毁时执行。不允许在aboutToDisappear函数中改变状态变量,特别是\@Link变量的修改可能会导致应用程序行为不稳定。
38
39**卡片能力:** 从API version 9开始,该接口支持在ArkTS卡片中使用。
40
41**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
42
43**系统能力:** SystemCapability.ArkUI.ArkUI.Full
44
45## onPageShow
46
47onPageShow?(): void
48
49页面每次显示时触发一次,包括路由过程、应用进入前台等场景,仅\@Entry装饰的自定义组件生效。
50
51**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
52
53**系统能力:** SystemCapability.ArkUI.ArkUI.Full
54
55## onPageHide
56
57onPageHide?(): void
58
59页面每次隐藏时触发一次,包括路由过程、应用进入后台等场景,仅\@Entry装饰的自定义组件生效。
60
61**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
62
63**系统能力:** SystemCapability.ArkUI.ArkUI.Full
64
65## onBackPress
66
67onBackPress?(): void | boolean
68
69当用户点击返回按钮时触发,仅\@Entry装饰的自定义组件生效。返回true表示页面自己处理返回逻辑,不进行页面路由;返回false表示使用默认的路由返回逻辑,不设置返回值按照false处理。
70
71**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
72
73**系统能力:** SystemCapability.ArkUI.ArkUI.Full
74
75```ts
76// xxx.ets
77@Entry
78@Component
79struct IndexComponent {
80  @State textColor: Color = Color.Black;
81
82  onPageShow() {
83    this.textColor = Color.Blue;
84    console.info('IndexComponent onPageShow');
85  }
86
87  onPageHide() {
88    this.textColor = Color.Transparent;
89    console.info('IndexComponent onPageHide');
90  }
91
92  onBackPress() {
93    this.textColor = Color.Red;
94    console.info('IndexComponent onBackPress');
95  }
96
97  build() {
98    Column() {
99      Text('Hello World')
100        .fontColor(this.textColor)
101        .fontSize(30)
102        .margin(30)
103    }.width('100%')
104  }
105}
106```
107![zh-cn_image_lifecycle](figures/zh-cn_image_lifecycle.gif)
108
109## aboutToReuse<sup>10+</sup>
110
111aboutToReuse?(params: { [key: string]: unknown }): void
112
113当一个可复用的自定义组件从复用缓存中重新加入到节点树时,触发aboutToReuse生命周期回调,并将组件的构造参数传递给aboutToReuse。
114
115**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
116
117**系统能力:** SystemCapability.ArkUI.ArkUI.Full
118
119**参数:**
120
121| 参数名    | 类型                         | 说明         |
122|--------|----------------------------|------------|
123| params | { [key: string]: unknown } | 自定义组件的构造参数。|
124
125```ts
126// xxx.ets
127export class Message {
128  value: string | undefined;
129
130  constructor(value: string) {
131    this.value = value
132  }
133}
134
135@Entry
136@Component
137struct Index {
138  @State switch: boolean = true
139
140  build() {
141    Column() {
142      Button('Hello World')
143        .fontSize(50)
144        .fontWeight(FontWeight.Bold)
145        .onClick(() => {
146          this.switch = !this.switch
147        })
148      if (this.switch) {
149        Child({ message: new Message('Child') })
150      }
151    }
152    .height("100%")
153    .width('100%')
154  }
155}
156
157@Reusable
158@Component
159struct Child {
160  @State message: Message = new Message('AboutToReuse');
161
162  aboutToReuse(params: Record<string, ESObject>) {
163    console.info("Recycle Child")
164    this.message = params.message as Message
165  }
166
167  build() {
168    Column() {
169      Text(this.message.value)
170        .fontSize(20)
171    }
172    .borderWidth(2)
173    .height(100)
174  }
175}
176```
177
178## aboutToRecycle<sup>10+</sup>
179
180aboutToRecycle?(): void
181
182组件的生命周期回调,在可复用组件从组件树上被加入到复用缓存之前调用。
183
184**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
185
186**系统能力:** SystemCapability.ArkUI.ArkUI.Full
187
188```ts
189// xxx.ets
190export class Message {
191  value: string | undefined;
192
193  constructor(value: string) {
194    this.value = value;
195  }
196}
197
198@Entry
199@Component
200struct Index {
201  @State switch: boolean = true;
202
203  build() {
204    Column() {
205      Button('Hello World')
206        .fontSize(50)
207        .fontWeight(FontWeight.Bold)
208        .onClick(() => {
209          this.switch = !this.switch;
210        })
211      if (this.switch) {
212        Child({ message: new Message('Child') })
213      }
214    }
215    .height("100%")
216    .width('100%')
217  }
218}
219
220@Reusable
221@Component
222struct Child {
223  @State message: Message = new Message('AboutToReuse');
224
225  aboutToReuse(params: Record<string, ESObject>) {
226    console.info("Reuse Child");
227    this.message = params.message as Message;
228  }
229
230  aboutToRecycle() {
231    //这里可以释放比较占内存的内容或其他非必要资源引用,避免一直占用内存,引发内存泄漏
232    console.info("Recycle Child,child进入复用池中");
233  }
234
235  build() {
236    Column() {
237      Text(this.message.value)
238        .fontSize(20)
239    }
240    .borderWidth(2)
241    .height(100)
242  }
243}
244```
245
246## onWillApplyTheme<sup>12+</sup>
247
248onWillApplyTheme?(theme: Theme): void
249
250onWillApplyTheme函数用于获取当前组件上下文的Theme对象,在创建自定义组件的新实例后,在执行其build()函数之前执行。允许在onWillApplyTheme函数中改变状态变量,更改将在后续执行build()函数中生效。
251
252**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
253
254**系统能力:** SystemCapability.ArkUI.ArkUI.Full
255
256**参数:**
257
258| 参数名    | 类型                                       | 说明         |
259|--------|------------------------------------------|------------|
260| theme | [Theme](../js-apis-arkui-theme.md#theme) | 自定义组件当前生效的Theme对象。|
261
262```ts
263// xxx.ets
264import { CustomTheme, CustomColors, Theme, ThemeControl } from '@kit.ArkUI';
265
266class BlueColors implements CustomColors {
267  fontPrimary = Color.White;
268  backgroundPrimary = Color.Blue;
269  brand = Color.Blue; //品牌色
270}
271
272class PageCustomTheme implements CustomTheme {
273  colors?: CustomColors;
274
275  constructor(colors: CustomColors) {
276    this.colors = colors;
277  }
278}
279const BlueColorsTheme = new PageCustomTheme(new BlueColors());
280// setDefaultTheme应该在应用入口页面调用或者在Ability中调用。
281ThemeControl.setDefaultTheme(BlueColorsTheme);
282
283@Entry
284@Component
285struct IndexComponent {
286  @State textColor: ResourceColor = $r('sys.color.font_primary');
287  @State columBgColor: ResourceColor = $r('sys.color.background_primary');
288
289  // onWillApplyTheme中可获取当前组件上下文的Theme对象。此处在onWillApplyTheme中将状态变量textColor、columBgColor,赋值为当前使用的Theme对象(BlueColorsTheme)中的配色。
290  onWillApplyTheme(theme: Theme) {
291    this.textColor = theme.colors.fontPrimary;
292    this.columBgColor = theme.colors.backgroundPrimary;
293    console.info('IndexComponent onWillApplyTheme');
294  }
295
296  build() {
297    Column() {
298      // 组件初始值配色样式
299      Column() {
300        Text('Hello World')
301          .fontColor($r('sys.color.font_primary'))
302          .fontSize(30)
303      }
304      .width('100%')
305      .height('25%')
306      .borderRadius('10vp')
307      .backgroundColor($r('sys.color.background_primary'))
308
309      // 组件颜色生效为onWillApplyTheme中配置颜色。
310      Column() {
311        Text('onWillApplyTheme')
312          .fontColor(this.textColor)
313          .fontSize(30)
314        Text('Hello World')
315          .fontColor(this.textColor)
316          .fontSize(30)
317      }
318      .width('100%')
319      .height('25%')
320      .borderRadius('10vp')
321      .backgroundColor(this.columBgColor)
322    }
323    .padding('16vp')
324    .backgroundColor('#dcdcdc')
325    .width('100%')
326    .height('100%')
327  }
328}
329```
330![onWillApplyThemePage](figures/onWillApplyTheme.png)