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óanew. - @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ốfreezeWhenInactivekiể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ố
LocalStoragehoặcEntryOptions. - @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.infotrự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ằngif. - 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)
}
}
}