HarmonyOS NEXT開發之ArkTS自定義元件學習筆記

威哥爱编程發表於2024-10-16

在HarmonyOS中,ArkTS提供了建立自定義元件的能力,允許開發者封裝和複用UI程式碼。以下是關於自定義元件的詳細介紹,包括建立自定義元件、頁面和自定義元件的生命週期、自定義元件的自定義佈局、凍結功能,以及程式碼案例分析。

建立自定義元件

自定義元件是基於struct實現的,使用@Component裝飾器來標識。每個自定義元件都必須實現build()方法,用於描述元件的UI結構。

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

在其他檔案中使用該自定義元件時,需要使用export關鍵字匯出,並在頁面中使用import匯入該元件 。

頁面和自定義元件生命週期

頁面生命週期僅限於被@Entry裝飾的元件,而自定義元件的生命週期僅限於被@Component裝飾的元件。

  • onPageShow:頁面每次顯示時觸發。
  • onPageHide:頁面每次隱藏時觸發。
  • onBackPress:當使用者點選返回按鈕時觸發。
  • aboutToAppear:元件即將出現時觸發。
  • aboutToDisappear:元件即將銷燬時觸發 。

自定義元件的自定義佈局

如果需要透過測算的方式佈局自定義元件內子元件的位置,可以使用onMeasureSizeonPlaceChildren介面。

@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裝飾的自定義元件支援凍結功能。當元件處於非啟用狀態時,狀態變數將不響應更新。

@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的自定義元件,它將顯示單個訂單項的詳細資訊。

// 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元件來顯示訂單資料。

// 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裝飾器定義,使其成為一個自定義元件。它接受三個屬性:orderIdorderDatestatus

  2. UI佈局:在OrderItembuild()方法中,我們使用Row佈局來水平排列三個Text元件,分別顯示訂單編號、日期和狀態。每個Text元件都設定了寬度、高度、字型大小和對齊方式,以確保佈局的整潔和一致性。

  3. 屬性傳遞OrderItem元件的屬性是透過@Prop裝飾器定義的,這允許父元件OrderList在建立OrderItem例項時傳遞這些屬性的值。

  4. 資料驅動OrderList元件的狀態變數orders包含了訂單資料。使用ForEach迴圈,我們為每個訂單項建立一個OrderItem元件例項,並將訂單資料作為屬性傳遞給它。

  5. 重用性OrderItem元件是可重用的,因為它封裝了訂單項的UI和邏輯,可以在OrderList頁面之外的其他部分使用,只需傳遞相應的屬性即可。

好了,這個案例展示瞭如何建立和使用自定義元件來構建HarmonyOS應用的UI,以及如何透過屬性傳遞和狀態管理來實現資料驅動的UI更新。關注威哥愛程式設計,你會發現他的世界裡,咖啡是燃料,鍵盤是樂器,而程式碼就是他的交響樂。每當夜深人靜,別人數羊,威哥數的是程式碼行數。🌙👨‍💻🎶

相關文章