• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 自定义组件的生命周期
2<!--Kit: ArkUI-->
3<!--Subsystem: ArkUI-->
4<!--Owner: @seaside_wu1; @huyisuo-->
5<!--Designer: @zhangboren-->
6<!--Tester: @TerryTsao-->
7<!--Adviser: @zhang_yixin13-->
8
9自定义组件的生命周期回调函数用于通知用户该自定义组件的生命周期,这些回调函数是私有的,在运行时由开发框架在特定的时间进行调用,不能从应用程序中手动调用这些回调函数。不要在多个窗口复用同一个自定义组件节点,其生命周期可能会紊乱。
10
11>**说明:**
12>
13>- 本模块首批接口从API version 7开始支持,后续版本的新增接口,采用上角标单独标记接口的起始版本。
14>- 允许在生命周期函数中使用Promise和异步回调函数,比如网络资源获取,定时器设置等。
15
16## build
17
18build(): void
19
20build()函数用于定义自定义组件的声明式UI描述,自定义组件必须定义build()函数。
21
22**卡片能力:** 从API version 9开始,该接口支持在ArkTS卡片中使用。
23
24**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
25
26**系统能力:** SystemCapability.ArkUI.ArkUI.Full
27
28## aboutToAppear
29
30aboutToAppear?(): void
31
32aboutToAppear函数在创建自定义组件的新实例后,在其build()函数执行前调用。允许在aboutToAppear函数中改变状态变量,更改将在后续执行build()函数中生效。实现自定义布局的自定义组件的aboutToAppear生命周期在布局过程中触发。
33
34> **说明:**
35>
36> * 在该回调函数内,建议仅执行当前节点组件的初始化逻辑,避免高耗时操作阻塞主线程。对于高耗时操作,推荐采用缓存或异步方案替代。最佳实践请参考[UI组件性能优化-避免在自定义组件的生命周期内执行高耗时操作](https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-ui-component-performance-optimization#section18755173594714)37> * 在需要频繁创建和销毁组件的场景中,将会频繁调用该回调函数。最佳实践请参考[主线程耗时操作优化指导-组件生命周期回调](https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-time-optimization-of-the-main-thread#section418843713435)38
39**卡片能力:** 从API version 9开始,该接口支持在ArkTS卡片中使用。
40
41**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
42
43**系统能力:** SystemCapability.ArkUI.ArkUI.Full
44
45## onDidBuild<sup>12+</sup>
46
47onDidBuild?(): void
48
49onDidBuild函数在自定义组件的build()函数执行后调用,开发者可以在这个阶段进行埋点数据上报等不影响实际UI的功能。不建议在onDidBuild函数中更改状态变量、使用animateTo等功能,这可能会导致不稳定的UI表现。
50
51**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
52
53**系统能力:** SystemCapability.ArkUI.ArkUI.Full
54
55## aboutToDisappear
56
57aboutToDisappear?(): void
58
59aboutToDisappear函数在自定义组件析构销毁时执行。不允许在aboutToDisappear函数中改变状态变量,特别是\@Link变量的修改可能会导致应用程序行为不稳定。
60
61> **说明:**
62>
63> 在需要频繁创建和销毁组件的场景中,将会频繁调用该回调函数。最佳实践请参考[主线程耗时操作优化指导-组件生命周期回调](https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-time-optimization-of-the-main-thread#section418843713435)64
65**卡片能力:** 从API version 9开始,该接口支持在ArkTS卡片中使用。
66
67**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
68
69**系统能力:** SystemCapability.ArkUI.ArkUI.Full
70
71## onPageShow
72
73onPageShow?(): void
74
75router路由页面(仅[\@Entry](../../../../application-dev/ui/state-management/arkts-create-custom-components.md#entry)装饰的自定义组件)每次显示时触发一次,包括路由跳转、应用进入前台等场景。
76
77**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
78
79**系统能力:** SystemCapability.ArkUI.ArkUI.Full
80
81## onPageHide
82
83onPageHide?(): void
84
85router路由页面每次隐藏时触发一次,包括路由跳转、应用进入后台等场景。
86
87> **说明:**
88>
89> 在该回调函数内,建议避免执行高耗时操作阻塞主线程造成卡顿。对于高耗时操作例如相机资源释放,推荐使用异步方案替代。最佳实践请参考[优化应用时延问题-延迟执行资源释放操作](https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-application-latency-optimization-cases#section8783201923819)90
91**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
92
93**系统能力:** SystemCapability.ArkUI.ArkUI.Full
94
95## onBackPress
96
97onBackPress?(): void | boolean
98
99当用户点击返回按钮时触发(仅router路由页面生效)。返回true表示页面自己处理返回逻辑,不进行页面路由;返回false表示使用默认的路由返回逻辑,不设置返回值按照false处理。
100
101**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
102
103**系统能力:** SystemCapability.ArkUI.ArkUI.Full
104
105**返回值:**
106
107| 类型                | 说明        |
108| ------------------- | --------- |
109| void \| boolean | 返回按钮动作。返回true表示页面自己处理返回逻辑,不进行页面路由;返回false表示使用默认的路由返回逻辑,不设置返回值按照false处理。 |
110
111```ts
112// xxx.ets
113@Entry
114@Component
115struct IndexComponent {
116  @State textColor: Color = Color.Black;
117
118  onPageShow() {
119    this.textColor = Color.Blue;
120    console.info('IndexComponent onPageShow');
121  }
122
123  onPageHide() {
124    this.textColor = Color.Transparent;
125    console.info('IndexComponent onPageHide');
126  }
127
128  onBackPress() {
129    this.textColor = Color.Red;
130    console.info('IndexComponent onBackPress');
131  }
132
133  build() {
134    Column() {
135      Text('Hello World')
136        .fontColor(this.textColor)
137        .fontSize(30)
138        .margin(30)
139    }.width('100%')
140  }
141}
142```
143![zh-cn_image_lifecycle](figures/zh-cn_image_lifecycle.gif)
144
145## onNewParam<sup>19+</sup>
146
147onNewParam?(param: ESObject): void
148
149该回调仅生效于由[\@Entry](../../../../application-dev/ui/state-management/arkts-create-custom-components.md#entry)装饰的、作为[router路由](../js-apis-router.md)页面存在的自定义组件。当之前存在于路由栈中的页面,通过[单实例模式](../js-apis-router.md#routermode9)移动到栈顶时触发该回调。
150
151**原子化服务API:** 从API version 19开始,该接口支持在原子化服务中使用。
152
153**系统能力:** SystemCapability.ArkUI.ArkUI.Full
154
155**参数:**
156
157| 参数名 | 类型     | 必填     |             说明         |
158|-------|----------|----------|---------------------------|
159| param | ESObject |是 | 路由跳转时传递到目标页面的数据。|
160
161```ts
162// pages/Index.ets
163import { router } from '@kit.ArkUI';
164
165export class routerParam {
166  msg: string = '__NA__';
167
168  constructor(msg: string) {
169    this.msg = msg;
170  }
171}
172
173@Entry
174@Component
175struct Index {
176  aboutToAppear(): void {
177    console.log('onNewParam', 'Index aboutToAppear');
178  }
179
180  onNewParam(param: ESObject) {
181    console.log('onNewParam', 'Index onNewParam, param: ' + JSON.stringify(param));
182  }
183
184  build() {
185    Column() {
186      Button('push pageOne Standard')
187        .margin(10)
188        .onClick(() => {
189          this.getUIContext().getRouter().pushUrl({
190            url: 'pages/PageOne',
191            params: new routerParam('push pageOne Standard')
192          }, router.RouterMode.Standard);
193        })
194      Button('push pageOne Single')
195        .margin(10)
196        .onClick(() => {
197          this.getUIContext().getRouter().pushUrl({
198            url: 'pages/PageOne',
199            params: new routerParam('push pageOne Single')
200          }, router.RouterMode.Single)
201        })
202    }
203    .width('100%')
204    .height('100%')
205  }
206}
207```
208<!--code_no_check-->
209```ts
210// pages/PageOne.ets
211import { router } from '@kit.ArkUI';
212import { routerParam } from './Index';
213
214@Entry
215@Component
216struct PageOne {
217  aboutToAppear(): void {
218    console.log('onNewParam', 'PageOne aboutToAppear');
219  }
220
221  onNewParam(param: ESObject) {
222    console.log('onNewParam', 'PageOne onNewParam, param: ' + JSON.stringify(param));
223  }
224
225  build() {
226    Column() {
227      Button('push Index Standard')
228        .margin(10)
229        .onClick(() => {
230          this.getUIContext().getRouter().pushUrl({
231            url: 'pages/Index',
232            params: new routerParam('push Index Standard')
233          }, router.RouterMode.Standard);
234        })
235      Button('push Index Single')
236        .margin(10)
237        .onClick(() => {
238          this.getUIContext().getRouter().pushUrl({
239            url: 'pages/Index',
240            params: new routerParam('push Index Single')
241          }, router.RouterMode.Single)
242        })
243    }
244    .width('100%')
245    .height('100%')
246  }
247}
248```
249
250## aboutToReuse<sup>10+</sup>
251
252aboutToReuse?(params: Record\<string, Object | undefined | null>): void
253
254当一个可复用的自定义组件从复用缓存中重新加入到节点树时,触发aboutToReuse生命周期回调,并将组件的构造参数传递给aboutToReuse。
255
256> **说明:**
257>
258> * [避免对@Link/@ObjectLink/@Prop等自动更新的状态变量,在aboutToReuse()中重复赋值](https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-component-reuse#section7441712174414)259> * 在滑动场景中,使用组件复用通常需要用该回调函数去更新组件的状态变量,因此在该回调函数中应避免耗时操作,否则会导致丢帧卡顿。最佳实践请参考[主线程耗时操作优化指导-组件复用回调](https://developer.huawei.com/consumer/cn/doc/best-practices/bpta-time-optimization-of-the-main-thread#section20815336174316)260
261**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
262
263**系统能力:** SystemCapability.ArkUI.ArkUI.Full
264
265**参数:**
266
267| 参数名  | 类型                                      | 必填 | 说明                |
268|--------|-------------------------------------------|-----|---------------------|
269| params | Record\<string, Object \| undefined \| null> |   是   | 自定义组件的构造参数。|
270
271```ts
272// xxx.ets
273export class Message {
274  value: string | undefined;
275
276  constructor(value: string) {
277    this.value = value
278  }
279}
280
281@Entry
282@Component
283struct Index {
284  @State switch: boolean = true
285
286  build() {
287    Column() {
288      Button('Hello World')
289        .fontSize(50)
290        .fontWeight(FontWeight.Bold)
291        .onClick(() => {
292          this.switch = !this.switch
293        })
294      if (this.switch) {
295        Child({ message: new Message('Child') })
296      }
297    }
298    .height("100%")
299    .width('100%')
300  }
301}
302
303@Reusable
304@Component
305struct Child {
306  @State message: Message = new Message('AboutToReuse');
307
308  aboutToReuse(params: Record<string, ESObject>) {
309    console.info("Recycle Child")
310    this.message = params.message as Message
311  }
312
313  build() {
314    Column() {
315      Text(this.message.value)
316        .fontSize(20)
317    }
318    .borderWidth(2)
319    .height(100)
320  }
321}
322```
323
324## aboutToReuse<sup>18+</sup>
325
326aboutToReuse?(): void
327
328当一个状态管理V2的可复用自定义组件从复用池被取出重新加入到节点树时,触发aboutToReuse生命周期回调。
329
330详细内容请参考[\@ReusableV2](../../../ui/state-management/arkts-new-reusableV2.md)。
331
332**原子化服务API:** 从API version 18开始,该接口支持在原子化服务中使用。
333
334**系统能力:** SystemCapability.ArkUI.ArkUI.Full
335
336```ts
337@Entry
338@ComponentV2
339struct Index {
340  @Local condition: boolean = true;
341  build() {
342    Column() {
343      Button('回收/复用').onClick(()=>{this.condition=!this.condition;}) // 点击切换回收/复用状态
344      if (this.condition) {
345        ReusableV2Component()
346      }
347    }
348  }
349}
350@ReusableV2
351@ComponentV2
352struct ReusableV2Component {
353  @Local message: string = 'Hello World';
354  aboutToReuse() {
355    console.log('ReusableV2Component aboutToReuse'); // 复用时被调用
356  }
357  build() {
358    Column() {
359      Text(this.message)
360    }
361  }
362}
363```
364
365
366## aboutToRecycle<sup>10+</sup>
367
368aboutToRecycle?(): void
369
370组件的生命周期回调,在可复用组件从组件树上被加入到复用缓存之前调用。
371
372**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
373
374**系统能力:** SystemCapability.ArkUI.ArkUI.Full
375
376```ts
377// xxx.ets
378export class Message {
379  value: string | undefined;
380
381  constructor(value: string) {
382    this.value = value;
383  }
384}
385
386@Entry
387@Component
388struct Index {
389  @State switch: boolean = true;
390
391  build() {
392    Column() {
393      Button('Hello World')
394        .fontSize(50)
395        .fontWeight(FontWeight.Bold)
396        .onClick(() => {
397          this.switch = !this.switch;
398        })
399      if (this.switch) {
400        Child({ message: new Message('Child') })
401      }
402    }
403    .height("100%")
404    .width('100%')
405  }
406}
407
408@Reusable
409@Component
410struct Child {
411  @State message: Message = new Message('AboutToReuse');
412
413  aboutToReuse(params: Record<string, ESObject>) {
414    console.info("Reuse Child");
415    this.message = params.message as Message;
416  }
417
418  aboutToRecycle() {
419    //这里可以释放比较占内存的内容或其他非必要资源引用,避免一直占用内存,引发内存泄漏
420    console.info("Recycle Child,child进入复用池中");
421  }
422
423  build() {
424    Column() {
425      Text(this.message.value)
426        .fontSize(20)
427    }
428    .borderWidth(2)
429    .height(100)
430  }
431}
432```
433
434## onWillApplyTheme<sup>12+</sup>
435
436onWillApplyTheme?(theme: Theme): void
437
438onWillApplyTheme函数用于获取当前组件上下文的Theme对象,在创建自定义组件的新实例后,在执行其build()函数之前执行。允许在onWillApplyTheme函数中改变状态变量,更改将在后续执行build()函数中生效。
439
440> **说明:**
441>
442> 从API version 18开始,该接口支持在状态管理V2组件中使用。
443
444**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
445
446**系统能力:** SystemCapability.ArkUI.ArkUI.Full
447
448**参数:**
449
450| 参数名    | 类型                                       | 必填    | 说明         |
451|--------|------------------------------------------|------------|-------------------------|
452| theme | [Theme](#theme12) | 是     | 自定义组件当前生效的Theme对象。|
453
454## Theme<sup>12+</sup>
455
456type Theme = Theme
457
458**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。
459
460**系统能力:** SystemCapability.ArkUI.ArkUI.Full
461
462| 类型                                                      | 说明                    |
463| --------------------------------------------------------- | ----------------------- |
464| [Theme](../js-apis-arkui-theme.md#theme) | 自定义组件当前生效的Theme对象。 |
465
466V1:
467
468```ts
469// xxx.ets
470import { CustomTheme, CustomColors, Theme, ThemeControl } from '@kit.ArkUI';
471
472class BlueColors implements CustomColors {
473  fontPrimary = Color.White;
474  backgroundPrimary = Color.Blue;
475  brand = Color.Blue; //品牌色
476}
477
478class PageCustomTheme implements CustomTheme {
479  colors?: CustomColors;
480
481  constructor(colors: CustomColors) {
482    this.colors = colors;
483  }
484}
485const BlueColorsTheme = new PageCustomTheme(new BlueColors());
486// setDefaultTheme应该在应用入口页面调用或者在Ability中调用。
487ThemeControl.setDefaultTheme(BlueColorsTheme);
488
489@Entry
490@Component
491struct IndexComponent {
492  @State textColor: ResourceColor = $r('sys.color.font_primary');
493  @State columBgColor: ResourceColor = $r('sys.color.background_primary');
494
495  // onWillApplyTheme中可获取当前组件上下文的Theme对象。此处在onWillApplyTheme中将状态变量textColor、columBgColor,赋值为当前使用的Theme对象(BlueColorsTheme)中的配色。
496  onWillApplyTheme(theme: Theme) {
497    this.textColor = theme.colors.fontPrimary;
498    this.columBgColor = theme.colors.backgroundPrimary;
499    console.info('IndexComponent onWillApplyTheme');
500  }
501
502  build() {
503    Column() {
504      // 组件初始值配色样式
505      Column() {
506        Text('Hello World')
507          .fontColor($r('sys.color.font_primary'))
508          .fontSize(30)
509      }
510      .width('100%')
511      .height('25%')
512      .borderRadius('10vp')
513      .backgroundColor($r('sys.color.background_primary'))
514
515      // 组件颜色生效为onWillApplyTheme中配置颜色。
516      Column() {
517        Text('onWillApplyTheme')
518          .fontColor(this.textColor)
519          .fontSize(30)
520        Text('Hello World')
521          .fontColor(this.textColor)
522          .fontSize(30)
523      }
524      .width('100%')
525      .height('25%')
526      .borderRadius('10vp')
527      .backgroundColor(this.columBgColor)
528    }
529    .padding('16vp')
530    .backgroundColor('#dcdcdc')
531    .width('100%')
532    .height('100%')
533  }
534}
535```
536![onWillApplyThemePage](figures/onWillApplyTheme.png)
537
538V2:
539
540```ts
541import { CustomTheme, CustomColors, Theme, ThemeControl } from '@kit.ArkUI';
542
543class BlueColors implements CustomColors {
544  fontPrimary = Color.White;
545  backgroundPrimary = Color.Blue;
546  brand = Color.Blue; //品牌色
547}
548
549class PageCustomTheme implements CustomTheme {
550  colors?: CustomColors;
551
552  constructor(colors: CustomColors) {
553    this.colors = colors;
554  }
555}
556
557const BlueColorsTheme = new PageCustomTheme(new BlueColors());
558// setDefaultTheme应该在应用入口页面调用或者在Ability中调用。
559ThemeControl.setDefaultTheme(BlueColorsTheme);
560
561@Entry
562@ComponentV2
563struct IndexComponent {
564  @Local textColor: ResourceColor = $r('sys.color.font_primary');
565  @Local columBgColor: ResourceColor = $r('sys.color.background_primary');
566
567  // onWillApplyTheme中可获取当前组件上下文的Theme对象。此处在onWillApplyTheme中将状态变量textColor、columBgColor,赋值为当前使用的Theme对象(BlueColorsTheme)中的配色。
568  onWillApplyTheme(theme: Theme) {
569    this.textColor = theme.colors.fontPrimary;
570    this.columBgColor = theme.colors.backgroundPrimary;
571    console.info('IndexComponent onWillApplyTheme');
572  }
573
574  build() {
575    Column() {
576      // 组件初始值配色样式
577      Column() {
578        Text('Hello World')
579          .fontColor($r('sys.color.font_primary'))
580          .fontSize(30)
581      }
582      .width('100%')
583      .height('25%')
584      .borderRadius('10vp')
585      .backgroundColor($r('sys.color.background_primary'))
586
587      // 组件颜色生效为onWillApplyTheme中配置颜色。
588      Column() {
589        Text('onWillApplyTheme')
590          .fontColor(this.textColor)
591          .fontSize(30)
592        Text('Hello World')
593          .fontColor(this.textColor)
594          .fontSize(30)
595      }
596      .width('100%')
597      .height('25%')
598      .borderRadius('10vp')
599      .backgroundColor(this.columBgColor)
600    }
601    .padding('16vp')
602    .backgroundColor('#dcdcdc')
603    .width('100%')
604    .height('100%')
605  }
606}
607```
608
609![onWillApplyTheme_V2](figures/onWillApplyTheme_V2.png)
610
611## pageTransition<sup>9+</sup>
612
613pageTransition?(): void
614
615进入此页面或移动到其他页面时实现动画。
616
617**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。
618
619**系统能力:** SystemCapability.ArkUI.ArkUI.Full