HarmonyOS NEXT开发 ArkTS自定义组件

摘要

在HarmonyOS中,ArkTS提供了创建自定义组件的能力,允许开发者封装和复用UI代码。以下是关于自定义组件的详细介绍,包括创建自定义组件、页面和自定义组件的生命周期、自定义组件的自定义布局、冻结功能,以及代码案例分析。

创建自定义组件

自定义组件是基于struct实现的,使用@Component装饰器来标识。每个自定义组件都必须实现build()方法,用于描述组件的UI结构。

TypeScript 复制代码
@Component
struct HelloComponent {
  @State message: string = 'Hello, World!';
  build() {
    Row() {
      Text(this.message)
        .onClick(() => {
          this.message = 'Hello, ArkUI!';
        })
    }
  }
}

在其他文件中使用该自定义组件时,需要使用export关键字导出,并在页面中使用import导入该组件。

页面和自定义组件生命周期

页面生命周期仅限于被@Entry装饰的组件,而自定义组件的生命周期仅限于被@Component装饰的组件。

  1. onPageShow:页面每次显示时触发。

  2. onPageHide:页面每次隐藏时触发。

  3. onBackPress:当用户点击返回按钮时触发。

  4. aboutToAppear:组件即将出现时触发。

  5. aboutToDisappear:组件即将销毁时触发 。

自定义组件的自定义布局

如果需要通过测算的方式布局自定义组件内子组件的位置,可以使用onMeasureSize和onPlaceChildren接口。

TypeScript 复制代码
@Component
struct CustomLayout {
  @Builder doNothingBuilder() {};
  @BuilderParam builder: () => void = this.doNothingBuilder;
  @State startSize: number = 100;
  result: SizeResult = { width: 0, height: 0 };
  onMeasureSize(selfLayoutInfo: GeometryInfo, children: Array<Measurable>, constraint: ConstraintSizeOptions) {
    let size = 100;
    children.forEach((child) => {
      let result: MeasureResult = child.measure({ minHeight: size, minWidth: size, maxWidth: size, maxHeight: size });
      size += result.width / 2;
    });
    this.result.width = 100;
    this.result.height = 400;
    return this.result;
  }
  onPlaceChildren(selfLayoutInfo: GeometryInfo, children: Array<Layoutable>, constraint: ConstraintSizeOptions) {
    let startPos = 300;
    children.forEach((child) => {
      let pos = startPos - child.measureResult.height;
      child.layout({ x: pos, y: pos });
    });
  }
  build() {
    this.builder();
  }
}

在这个例子中,CustomLayout组件通过onMeasureSizeonPlaceChildren设置了子组件的大小和位置 。

自定义组件冻结功能

从API version 12 开始,@ComponentV2装饰的自定义组件支持冻结功能。当组件处于非激活状态时,状态变量将不响应更新。

TypeScript 复制代码
@Entry@ComponentV2({ freezeWhenInactive: true })
struct FirstTest {
  build() {
    Column() {
      Text(`From first Page ${book.page}`).fontSize(50)
      Button('first page + 1').fontSize(30)
        .onClick(() => {
          book.page += 1;
        })
      Button('go to next page').fontSize(30)
        .onClick(() => {
          router.pushUrl({ url: 'pages/Page' });
        })
    }
  }
}

在这个例子中,当页面A跳转到页面B时,页面A的状态变为非激活,组件的更新将被冻结 。

通过这些功能,开发者可以创建可复用、响应式且具有复杂布局的自定义组件,从而提升HarmonyOS应用的开发效率和用户体验。

自定义组件案例:订单列表页面

假设我们需要开发一个HarmonyOS应用,其中包含一个订单列表页面。这个页面将显示一个订单项的自定义组件,每个订单项包含订单编号、日期和订单状态。我们希望这个自定义组件是可重用的,以便在应用的其他部分也可以使用它。

步骤 1: 创建自定义组件

首先,我们创建一个名为OrderItem的自定义组件,它将显示单个订单项的详细信息。

TypeScript 复制代码
// OrderItem.ets
@Component
export struct OrderItem {
  @Prop orderId: string;
  @Prop orderDate: string;
  @Prop status: string;

  build() {
    Row() {
      Text(this.orderId).width(200).height(60).fontSize(16).alignItems(HorizontalAlign.Start);
      Text(this.orderDate).width(150).height(60).fontSize(14).alignItems(HorizontalAlign.Center);
      Text(this.status).width(100).height(60).fontSize(14).alignItems(HorizontalAlign.End);
    }.padding(10).backgroundColor(Color.White).border({ width: 1, color: Color.Grey });
  }
}

在这个组件中,我们使用了@Prop装饰器来定义属性,这些属性将由父组件传递。build()方法定义了订单项的UI结构,使用了Row布局来水平排列订单编号、日期和状态。

步骤 2: 使用自定义组件

接下来,我们在订单列表页面中使用OrderItem组件来显示订单数据。

TypeScript 复制代码
// OrderList.ets
import { OrderItem } from './OrderItem';

@Entry
@Component
struct OrderList {
  @State orders: Array<{ orderId: string; orderDate: string; status: string }> = [
    { orderId: '001', orderDate: '2024-04-01', status: 'Completed' },
    { orderId: '002', orderDate: '2024-04-02', status: 'Shipped' },
    // 更多订单...
  ];

  build() {
    Column() {
      ForEach(this.orders, (order) => {
        OrderItem({
          orderId: order.orderId,
          orderDate: order.orderDate,
          status: order.status,
        });
      });
    }.spacing(10).padding(10);
  }
}

在OrderList组件中,我们定义了一个状态变量orders来存储订单数据。在build()方法中,我们使用ForEach循环来遍历订单数组,并为每个订单创建一个OrderItem组件实例,传递相应的属性。

详细解释

1.自定义组件的定义:OrderItem组件通过@Component装饰器定义,使其成为一个自定义组件。它接受三个属性:orderId、orderDate和status。

2.UI布局:在OrderItem的build()方法中,我们使用Row布局来水平排列三个Text组件,分别显示订单编号、日期和状态。每个Text组件都设置了宽度、高度、字体大小和对齐方式,以确保布局的整洁和一致性。

3.属性传递:OrderItem组件的属性是通过@Prop装饰器定义的,这允许父组件OrderList在创建OrderItem实例时传递这些属性的值。

4.数据驱动:OrderList组件的状态变量orders包含了订单数据。使用ForEach循环,我们为每个订单项创建一个OrderItem组件实例,并将订单数据作为属性传递给它。

5.重用性:OrderItem组件是可重用的,因为它封装了订单项的UI和逻辑,可以在OrderList页面之外的其他部分使用,只需传递相应的属性即可。

相关推荐
国服第二切图仔20 小时前
Electron for 鸿蒙PC项目实战之拖拽组件示例
javascript·electron·harmonyos
国服第二切图仔20 小时前
Electron for鸿蒙PC项目实战之天气预报应用
javascript·electron·harmonyos·鸿蒙pc
国服第二切图仔21 小时前
Electron for鸿蒙PC项目之侧边栏组件示例
javascript·electron·harmonyos·鸿蒙pc
RisunJan21 小时前
HarmonyOS 系统概述
华为·harmonyos
泓博21 小时前
鸿蒙网络请求流式返回实现方法
华为·harmonyos
国服第二切图仔1 天前
Electron for鸿蒙pc项目实战之下拉菜单组件
javascript·electron·harmonyos·鸿蒙pc
汉堡黄•᷄ࡇ•᷅1 天前
鸿蒙开发:案例集合List:多级列表(商品分类)
harmonyos·鸿蒙·鸿蒙系统
北方的流星1 天前
华为AC+AP旁挂式三层无线局域网的配置案例
运维·网络·经验分享·华为
国服第二切图仔1 天前
Electron for 鸿蒙PC项目开发之模态框组件
javascript·electron·harmonyos