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

在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更新。關注威哥愛編程,你會發現他的世界里,咖啡是燃料,鍵盤是樂器,而代碼就是他的交響樂。每當夜深人靜,別人數羊,威哥數的是代碼行數。????????

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容