鸿蒙UI开发快速入门 —— part07:组件状态管理之@Prop/@Link装饰器

1、前言

我们在上一章学习了@State装饰器,@State装饰器的作用范围仅仅在当前组件,接下来,我们讨论如何从父组件中传入参数到子组件,让子组件随着父组件的状态发生变化。本章将要介绍的就是:@Props装饰器。

2、@Props装饰器

@Prop装饰的变量可以和父组件建立单向的同步关系。@Prop装饰的变量是可变的,但是变化不会同步回其父组件。

  • @Prop变量允许在本地修改和初始化,但修改后的变化不会同步回父组件。

  • 当父组件中的数据源更改时,与之相关的@Prop装饰的变量都会自动更新。如果子组件已经在本地修改了@Prop装饰的相关变量值,而在父组件中对应的@State装饰的变量被修改后,子组件本地修改的@Prop装饰的相关变量值将被覆盖。

  • @Prop装饰器不能在@Entry装饰的自定义组件中使用。

  • 装饰器允许装饰的变量类型有:string、number、boolean、enum类型。不支持any,不允许使用undefined和null。

  • 装饰的变量必须指定类型,在父组件中,传递给@Prop装饰的值不能为undefined或者null;

  • @Prop装饰的变量和父组件状态变量类型相同,即@Prop : S和@State : S

  • 虽然说@Props装饰的变量可由父组件初始化,但使用范围依旧只能在组件内访问。

核心代码结构如下:

@Componentstruct Child {
  
   // 子组件中的@Props变量,可以被父组件初始化  @Prop count: number;}@Entrystruct Parent {
  
    @State parentCount:number = 1;  build() {
  
    // 此时,父组件就将本地parentCount变量传递给了子组件  // 当parentCount发生变化时,子组件也会刷新  Child({count: this.parentCount});  }}

3、@Props装饰器的简单使用Demo

以下示例是@State到子组件@Prop简单数据同步,

父组件ParentComponent的状态变量countDownStartValue初始化子组件CountDownComponent中@Prop装饰的count,

点击“Try again”,count的修改仅保留在CountDownComponent,不会同步给父组件ParentComponent。

ParentComponent的状态变量countDownStartValue的变化将重置CountDownComponent的count。

@Componentstruct CountDownComponent {
  
    @Prop count: number;  costOfOneAttempt: num
在ArkTS中,`ForEach` 和 `LazyForEach` 是用于遍历数据并渲染组件的两种方式,它们在性能和使用场景上有显著区别。同时,`@Prop` 和 `@ObjectLink` 装饰器用于组件间的数据传递,但它们在响应式更新机制和适用对象上有不同用途。 ### ForEach 与 LazyForEach 的区别 `ForEach` 是一种同步遍历方式,适用于数据量较小且需要一次性渲染所有子组件的场景。它会立即为数据集中的每个元素创建对应的组件树,并将其渲染到界面上。这种方式适合静态数据或数据量不大的情况,但不适用于大数据集,因为它会导致内存占用过高。 ```typescript ForEach(this.items, (item: string) => { Text(item) }) ``` `LazyForEach` 是一种异步遍历方式,主要用于处理大数据集或需要懒加载的场景。它只渲染当前可见区域的组件,当用户滚动时,动态加载和卸载组件。这种方式可以显著提升性能,尤其是在处理大量数据时。`LazyForEach` 通常与 `Scroll` 组件结合使用,以实现高效的列表渲染。 ```typescript LazyForEach(this.items, (item: string) => { Text(item) }) ``` ### @Prop 与 @ObjectLink 的区别 `@Prop` 装饰器用于在父子组件之间传递数据,适用于从父组件向子组件传递基本类型或对象的情况。当父组件中的数据发生变化时,子组件会自动更新。`@Prop` 的特点是它会创建一个从父组件到子组件的单向绑定,子组件不能直接修改 `@Prop` 的值。 ```typescript @Component struct ChildComponent { @Prop message: string; build() { Text(this.message) } } ``` `@ObjectLink` 装饰器用于在父子组件之间传递对象,并且允许子组件对对象的属性进行修改。与 `@Prop` 不同,`@ObjectLink` 创建的是一个双向绑定,父组件中的对象属性会随着子组件中的修改而更新。`@ObjectLink` 适用于需要在子组件中修改父组件对象属性的场景。 ```typescript @Component struct ChildComponent { @ObjectLink item: { count: number }; build() { Button(`Count: ${this.item.count}`) .onClick(() => { this.item.count++; }) } } ``` ### 组件封装 在ArkTS中,组件封装是构建可复用UI组件的关键。通过将常用的UI结构和逻辑封装到自定义组件中,可以提高代码的可维护性和复用性。组件封装通常涉及使用 `@Component` 装饰器定义组件,并通过 `@Prop` 或 `@ObjectLink` 传递数据。 ```typescript @Component struct CustomButton { @Prop text: string; build() { Button(this.text) .width(100) .height(50) .backgroundColor("#00B42A") } } ``` ### 页面布局优化 页面布局优化主要关注如何高效地组织和渲染UI组件,以提升应用的性能和用户体验。以下是一些常见的优化策略: 1. **使用 `LazyForEach`**:对于大数据集的列表,使用 `LazyForEach` 可以避免一次性渲染所有组件,从而减少内存占用并提高性能。 2. **避免不必要的嵌套**:减少布局的嵌套层级可以降低渲染复杂度,提升性能。 3. **使用 `Flex` 布局**:`Flex` 布局提供了灵活的对齐和分布选项,能够帮助开发者更高效地设计响应式界面。 4. **合理使用 `State` 和 `Link`**:通过 `@State` 和 `@Link` 装饰器管理组件内部和组件间的状态,确保状态变化时只更新受影响的部分,避免不必要的重新渲染。 ```typescript @Entry @Component struct OptimizedLayout { @State items: string[] = ["Item 1", "Item 2", "Item 3"]; build() { Column() { LazyForEach(this.items, (item: string) => { Text(item) .fontSize(20) .margin(10) }) } .width("100%") .height("100%") } } ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值