Tạo thành phần tùy chỉnh trong HarmonyOS Next

Việc xây dựng giao diện người dùng linh hoạt và dễ bảo trì trong HarmonyOS Next phụ thuộc rất lớn vào khả năng tạo các thành phần tùy chỉnh. Những thành phần này hỗ trợ tái sử dụng, kết hợp linh hoạt và cập nhật giao diện theo dữ liệu, giúp tách biệt rõ ràng giữa logic nghiệp vụ và giao diện.

Cấu trúc cơ bản của thành phần tùy chỉnh

  • Dùng struct: Thành phần được khai báo bằng struct TênThànhPhần { ... }, không kế thừa, không trùng tên với thành phần hệ thống. Có thể khởi tạo mà không cần từ khóa new.
  • @Component: Chỉ áp dụng cho struct, bắt buộc phải có hàm build(). Từ API version 11, hỗ trợ tham số freezeWhenInactive kiểu boolean để điều khiển trạng thái đóng băng.
  • build(): Hàm bắt buộc, mô tả cấu trúc UI dạng khai báo.
  • @Entry: Đánh dấu thành phần là điểm vào của trang. Mỗi trang chỉ có một thành phần được đánh dấu này. Từ API version 10, hỗ trợ truyền thêm tham số LocalStorage hoặc EntryOptions.
  • @Reusable: Cho phép tái sử dụng thành phần trong ArkTS widget (từ API version 10).

Hàm và biến thành viên

  • Hàm và biến thành viên đều là private, không khuyến khích khai báo static.
  • Khởi tạo biến có thể thực hiện trực tiếp trong struct hoặc nhận giá trị từ component cha qua props.

Quy tắc truyền tham số

@Component
struct DemNguoc {
  private giaTri: number = 0;
  private mauSac: Color = Color.Blue;

  build() { /* UI */ }
}

@Entry
@Component
struct Cha {
  private mau: Color = Color.Pink;

  build() {
    Column() {
      DemNguoc({ giaTri: 10, mauSac: this.mau })
    }
  }
}

Truyền hàm làm tham số

@Entry
@Component
struct GiaoDienChinh {
  @State dem: number = 0

  tangGiaTri = () => {
    this.dem++;
  }

  build() {
    Column() {
      Text(`${this.dem}`)
      NutTang({ hamXuLy: this.tangGiaTri })
    }
  }
}

@Component
struct NutTang {
  hamXuLy?: () => void

  build() {
    Button('Tăng')
      .width(80)
      .onClick(() => {
        if (this.hamXuLy) this.hamXuLy();
      })
  }
}

Quy tắc hàm build()

  • Thành phần có @Entry: root node phải là container, duy nhất, không được là ForEach.
  • Thành phần có @Component: root node có thể không phải container, nhưng vẫn phải duy nhất và không là ForEach.
  • Không khai báo biến cục bộ bên trong build().
  • Không gọi console.info trực tiếp trong mô tả UI (chỉ dùng trong hàm).
  • Không tạo scope cục bộ.
  • Không gọi hàm chưa được gắn @Builder.
  • Không dùng switch, thay bằng if.
  • Không dùng biểu thức trực tiếp.
  • Không thay đổi trực tiếp biến trạng thái trong build() để tránh vòng lặp render.

Áp dụng style chung

Khi thiết lập style cho thành phần tùy chỉnh, thực chất là đang bao nó trong một container ẩn và áp dụng style lên container đó:

@Component
struct NutChao {
  build() {
    Button('Xin chào')
  }
}

@Entry
@Component
struct TrangChu {
  build() {
    Row() {
      NutChao()
        .width(200)
        .height(300)
        .backgroundColor(Color.Red)
    }
  }
}

Thẻ: HarmonyOS ArkTS CustomComponent UIFramework StateManagement

Đăng vào ngày 10 tháng 6 lúc 20:04