Trong phát triển HarmonyOS Next, ArkTS áp dụng các quy tắc xác minh cụ thể đối với các trình trang (access modifiers) private/public/protected được sử dụng trên biến thành viên của thành phần tùy chỉnh. Việc sử dụng không đúng quy định sẽ dẫn đến các thông báo nhật ký tương ứng.
Tổng quan hạn chế sử dụng
Hạn chế liên quan đến trình trang private
Khi sử dụng trình trang private cho các biến như @State/@Prop/@Provide/@BuilderParam hoặc các biến thành viên thông thường (không liên quan đến cập nhật), việc gán giá trị truyền tham số trong quá trình xây dựng thành phần tùy chỉnh là không được phép, nếu không sẽ xuất hiện cảnh báo biên dịch.
Hạn chế liên quan đến trình trang public
Việc sử dụng trình trang public cho các biến @StorageLink/@StorageProp/@LocalStorageLink/@LocalStorageProp/@Consume sẽ gây ra cảnh báo biên dịch.
Hạn chế khi kết hợp private với trình trang đặc biệt
Việc sử dụng trình trang private cho các biến @Link/@ObjectLink sẽ gây ra cảnh báo biên dịch.
Hạn chế trình trang protected
Vì struct không hỗ trợ kế thừa, nên việc sử dụng trình trang protected cho bất kỳ biến nào kể trên đều gây ra cảnh báo biên dịch.
Hạn chế kết hợp @Require và private
Khi cả @Require và private cùng được áp dụng cho các biến thành viên như @State/@Prop/@Provide/@BuilderParam hoặc các biến thông thường trong struct thành phần tùy chỉnh, sẽ có cảnh báo biên dịch.
Ví dụ về trường hợp sử dụng sai
Kết hợp private với @State/@Prop/@Provide/@BuilderParam
Ví dụ mã nguồn
@Entry
@Component
struct AccessConstraints {
@Builder
createTest() {
Text("Parent builder")
}
build() {
Column() {
ChildComponent({
statusValue: "Hello",
propertyValue: "Hello",
supplyValue: "Hello",
builderFunction: this.createTest,
normalValue: "Hello"
})
}
.width('100%')
}
}
@Component
struct ChildComponent {
@State private statusValue: string = "Hello";
@Prop private propertyValue: string = "Hello";
@Provide private supplyValue: string = "Hello";
@BuilderParam private builderFunction: () => void = this.createTest;
private normalValue: string = "Hello";
@Builder
createTest() {
Text("Child builder")
}
build() {
Column() {
Text("Hello")
.fontSize(50)
.fontWeight(FontWeight.Bold)
}
}
}
Nhật ký cảnh báo biên dịch
- Property 'statusValue' is private and can not be initialized through the component constructor.
- Property 'propertyValue' is private and can not be initialized through the component constructor.
- Property 'supplyValue' is private and can not be initialized through the component constructor.
- Property 'builderFunction' is private and can not be initialized through the component constructor.
- Property 'normalValue' is private and can not be initialized through the component constructor.
Kết hợp public với @StorageLink/@StorageProp/@LocalStorageLink/@LocalStorageProp/@Consume
Ví dụ mã nguồn
@Entry
@Component
struct AccessConstraints {
@Provide consumerValue: string = "Hello";
build() {
Column() {
ChildElement()
}
.width('100%')
}
}
@Component
struct ChildElement {
@LocalStorageProp("sessionLocalProp") public localPropertyValue: string = "Hello";
@LocalStorageLink("sessionLocalLink") public localLinkValue: string = "Hello";
@StorageProp("sessionProp") public storagePropertyValue: string = "Hello";
@StorageLink("sessionLink") public storageLinkValue: string = "Hello";
@Consume public consumerValue: string;
build() {
Column() {
Text("Hello")
.fontSize(50)
.fontWeight(FontWeight.Bold)
}
}
}
Nhật ký cảnh báo biên dịch
- Property 'localPropertyValue' can not be decorated with both @LocalStorageProp and public.
- Property 'localLinkValue' can not be decorated with both @LocalStorageLink and public.
- Property 'storagePropertyValue' can not be decorated with both @StorageProp and public.
- Property 'storageLinkValue' can not be decorated with both @StorageLink and public.
- Property 'consumerValue' can not be decorated with both @Consume and public.
Kết hợp private với @Link/@ObjectLink
Ví dụ mã nguồn
@Entry
@Component
struct AccessConstraints {
@State linkData: string = "Hello";
@State objectLinkData: CustomObject = new CustomObject();
build() {
Column() {
ChildElement({linkData: this.linkData, objectLinkData: this.objectLinkData})
}
.width('100%')
}
}
@Observed
class CustomObject {
counter: number = 0;
}
@Component
struct ChildElement {
@Link private linkData: string;
@ObjectLink private objectLinkData: CustomObject;
build() {
Column() {
Text("Hello")
.fontSize(50)
.fontWeight(FontWeight.Bold)
}
}
}
Nhật ký cảnh báo biên dịch
- Property 'linkData' can not be decorated with both @Link and private.
- Property 'objectLinkData' can not be decorated with both @ObjectLink and private.
Sử dụng trình trang protected
Ví dụ mã nguồn
@Entry
@Component
struct AccessConstraints {
build() {
Column() {
ChildElement({normalData: "Hello"})
}
.width('100%')
}
}
@Component
struct ChildElement {
protected normalData: string = "Hello";
build() {
Column() {
Text("Hello")
.fontSize(50)
.fontWeight(FontWeight.Bold)
}
}
}
Nhật ký cảnh báo biên dịch
- The member attributes of a struct can not be protected.
Kết hợp private, @Require với @State/@Prop/@Provide/@BuilderParam
Ví dụ mã nguồn
@Entry
@Component
struct AccessConstraints {
build() {
Column() {
ChildElement({propertyData: "Hello"})
}
.width('100%')
}
}
@Component
struct ChildElement {
@Require @Prop private propertyData: string = "Hello";
build() {
Column() {
Text("Hello")
.fontSize(50)
.fontWeight(FontWeight.Bold)
}
}
}
Nhật ký cảnh báo biên dịch
- Property 'propertyData' can not be decorated with both @Require and private.
- Property 'propertyData' is private and can not be initialized through the component constructor.
Khi sử dụng thành phần tùy chỉnh HarmonyOS Next, nhà phát triển cần tuân thủ các quy tắc sử dụng trình trang này để tránh cảnh báo biên dịch do sử dụng không đúng quy định, đảm bảo việc xây dựng và thực hiện chức năng của thành phần được chính xác. Đồng thời, lưu ý rằng các quy tắc này được hỗ trợ từ API version 12 trở đi, trong quá trình phát triển cần xử lý phù hợp dựa trên phiên bản API thực tế.