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](../../../../application-dev/ui/state-management/arkts-create-custom-components.md#entry)装饰的自定义组件作为页面时生效。 50 51**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 52 53**系统能力:** SystemCapability.ArkUI.ArkUI.Full 54 55## onPageHide 56 57onPageHide?(): void 58 59页面每次隐藏时触发一次,包括路由过程、应用进入后台等场景,仅[\@Entry](../../../../application-dev/ui/state-management/arkts-create-custom-components.md#entry)装饰的自定义组件作为页面时生效。 60 61**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 62 63**系统能力:** SystemCapability.ArkUI.ArkUI.Full 64 65## onBackPress 66 67onBackPress?(): void | boolean 68 69当用户点击返回按钮时触发,仅[\@Entry](../../../../application-dev/ui/state-management/arkts-create-custom-components.md#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 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## aboutToReuse<sup>18+</sup> 179 180aboutToReuse?(): void 181 182当一个状态管理V2的可复用自定义组件从复用池被取出重新加入到节点树时,触发aboutToReuse生命周期回调。 183 184详细内容请参考[\@ReusableV2](../../../ui/state-management/arkts-new-reusableV2.md)。 185 186**原子化服务API:** 从API version 18开始,该接口支持在原子化服务中使用。 187 188**系统能力:** SystemCapability.ArkUI.ArkUI.Full 189 190```ts 191@Entry 192@ComponentV2 193struct Index { 194 @Local condition: boolean = true; 195 build() { 196 Column() { 197 Button('回收/复用').onClick(()=>{this.condition=!this.condition;}) // 点击切换回收/复用状态 198 if (this.condition) { 199 ReusableV2Component() 200 } 201 } 202 } 203} 204@ReusableV2 205@ComponentV2 206struct ReusableV2Component { 207 @Local message: string = 'Hello World'; 208 aboutToReuse() { 209 console.log('ReusableV2Component aboutToReuse'); // 复用时被调用 210 } 211 build() { 212 Column() { 213 Text(this.message) 214 } 215 } 216} 217``` 218 219 220## aboutToRecycle<sup>10+</sup> 221 222aboutToRecycle?(): void 223 224组件的生命周期回调,在可复用组件从组件树上被加入到复用缓存之前调用。 225 226**原子化服务API:** 从API version 11开始,该接口支持在原子化服务中使用。 227 228**系统能力:** SystemCapability.ArkUI.ArkUI.Full 229 230```ts 231// xxx.ets 232export class Message { 233 value: string | undefined; 234 235 constructor(value: string) { 236 this.value = value; 237 } 238} 239 240@Entry 241@Component 242struct Index { 243 @State switch: boolean = true; 244 245 build() { 246 Column() { 247 Button('Hello World') 248 .fontSize(50) 249 .fontWeight(FontWeight.Bold) 250 .onClick(() => { 251 this.switch = !this.switch; 252 }) 253 if (this.switch) { 254 Child({ message: new Message('Child') }) 255 } 256 } 257 .height("100%") 258 .width('100%') 259 } 260} 261 262@Reusable 263@Component 264struct Child { 265 @State message: Message = new Message('AboutToReuse'); 266 267 aboutToReuse(params: Record<string, ESObject>) { 268 console.info("Reuse Child"); 269 this.message = params.message as Message; 270 } 271 272 aboutToRecycle() { 273 //这里可以释放比较占内存的内容或其他非必要资源引用,避免一直占用内存,引发内存泄漏 274 console.info("Recycle Child,child进入复用池中"); 275 } 276 277 build() { 278 Column() { 279 Text(this.message.value) 280 .fontSize(20) 281 } 282 .borderWidth(2) 283 .height(100) 284 } 285} 286``` 287 288## onWillApplyTheme<sup>12+</sup> 289 290onWillApplyTheme?(theme: Theme): void 291 292onWillApplyTheme函数用于获取当前组件上下文的Theme对象,在创建自定义组件的新实例后,在执行其build()函数之前执行。允许在onWillApplyTheme函数中改变状态变量,更改将在后续执行build()函数中生效。 293 294> **说明:** 295> 296> 从API version 18开始,该接口支持在状态管理V2组件中使用。 297 298**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 299 300**系统能力:** SystemCapability.ArkUI.ArkUI.Full 301 302**参数:** 303 304| 参数名 | 类型 | 说明 | 305|--------|------------------------------------------|------------| 306| theme | [Theme](../js-apis-arkui-theme.md#theme) | 自定义组件当前生效的Theme对象。| 307 308V1: 309 310```ts 311// xxx.ets 312import { CustomTheme, CustomColors, Theme, ThemeControl } from '@kit.ArkUI'; 313 314class BlueColors implements CustomColors { 315 fontPrimary = Color.White; 316 backgroundPrimary = Color.Blue; 317 brand = Color.Blue; //品牌色 318} 319 320class PageCustomTheme implements CustomTheme { 321 colors?: CustomColors; 322 323 constructor(colors: CustomColors) { 324 this.colors = colors; 325 } 326} 327const BlueColorsTheme = new PageCustomTheme(new BlueColors()); 328// setDefaultTheme应该在应用入口页面调用或者在Ability中调用。 329ThemeControl.setDefaultTheme(BlueColorsTheme); 330 331@Entry 332@Component 333struct IndexComponent { 334 @State textColor: ResourceColor = $r('sys.color.font_primary'); 335 @State columBgColor: ResourceColor = $r('sys.color.background_primary'); 336 337 // onWillApplyTheme中可获取当前组件上下文的Theme对象。此处在onWillApplyTheme中将状态变量textColor、columBgColor,赋值为当前使用的Theme对象(BlueColorsTheme)中的配色。 338 onWillApplyTheme(theme: Theme) { 339 this.textColor = theme.colors.fontPrimary; 340 this.columBgColor = theme.colors.backgroundPrimary; 341 console.info('IndexComponent onWillApplyTheme'); 342 } 343 344 build() { 345 Column() { 346 // 组件初始值配色样式 347 Column() { 348 Text('Hello World') 349 .fontColor($r('sys.color.font_primary')) 350 .fontSize(30) 351 } 352 .width('100%') 353 .height('25%') 354 .borderRadius('10vp') 355 .backgroundColor($r('sys.color.background_primary')) 356 357 // 组件颜色生效为onWillApplyTheme中配置颜色。 358 Column() { 359 Text('onWillApplyTheme') 360 .fontColor(this.textColor) 361 .fontSize(30) 362 Text('Hello World') 363 .fontColor(this.textColor) 364 .fontSize(30) 365 } 366 .width('100%') 367 .height('25%') 368 .borderRadius('10vp') 369 .backgroundColor(this.columBgColor) 370 } 371 .padding('16vp') 372 .backgroundColor('#dcdcdc') 373 .width('100%') 374 .height('100%') 375 } 376} 377``` 378 379 380V2: 381 382```ts 383import { CustomTheme, CustomColors, Theme, ThemeControl } from '@kit.ArkUI'; 384 385class BlueColors implements CustomColors { 386 fontPrimary = Color.White; 387 backgroundPrimary = Color.Blue; 388 brand = Color.Blue; //品牌色 389} 390 391class PageCustomTheme implements CustomTheme { 392 colors?: CustomColors; 393 394 constructor(colors: CustomColors) { 395 this.colors = colors; 396 } 397} 398 399const BlueColorsTheme = new PageCustomTheme(new BlueColors()); 400// setDefaultTheme应该在应用入口页面调用或者在Ability中调用。 401ThemeControl.setDefaultTheme(BlueColorsTheme); 402 403@Entry 404@ComponentV2 405struct IndexComponent { 406 @Local textColor: ResourceColor = $r('sys.color.font_primary'); 407 @Local columBgColor: ResourceColor = $r('sys.color.background_primary'); 408 409 // onWillApplyTheme中可获取当前组件上下文的Theme对象。此处在onWillApplyTheme中将状态变量textColor、columBgColor,赋值为当前使用的Theme对象(BlueColorsTheme)中的配色。 410 onWillApplyTheme(theme: Theme) { 411 this.textColor = theme.colors.fontPrimary; 412 this.columBgColor = theme.colors.backgroundPrimary; 413 console.info('IndexComponent onWillApplyTheme'); 414 } 415 416 build() { 417 Column() { 418 // 组件初始值配色样式 419 Column() { 420 Text('Hello World') 421 .fontColor($r('sys.color.font_primary')) 422 .fontSize(30) 423 } 424 .width('100%') 425 .height('25%') 426 .borderRadius('10vp') 427 .backgroundColor($r('sys.color.background_primary')) 428 429 // 组件颜色生效为onWillApplyTheme中配置颜色。 430 Column() { 431 Text('onWillApplyTheme') 432 .fontColor(this.textColor) 433 .fontSize(30) 434 Text('Hello World') 435 .fontColor(this.textColor) 436 .fontSize(30) 437 } 438 .width('100%') 439 .height('25%') 440 .borderRadius('10vp') 441 .backgroundColor(this.columBgColor) 442 } 443 .padding('16vp') 444 .backgroundColor('#dcdcdc') 445 .width('100%') 446 .height('100%') 447 } 448} 449``` 450 451