自定義組件
創(chuàng)建自定義組件
在ArkUI中,UI顯示的內(nèi)容均為組件,由框架直接提供的稱為系統(tǒng)組件,由開發(fā)者定義的稱為自定義組件。在進行 UI 界面開發(fā)時,通常不是簡單的將系統(tǒng)組件進行組合使用,而是需要考慮代碼可復用性、業(yè)務邏輯與UI分離,后續(xù)版本演進等因素。因此,將UI和部分業(yè)務邏輯封裝成自定義組件是不可或缺的能力。
自定義組件具有以下特點:
- 可組合:允許開發(fā)者組合使用系統(tǒng)組件、及其屬性和方法。
- 可重用:自定義組件可以被其他組件重用,并作為不同的實例在不同的父組件或容器中使用。
- 數(shù)據(jù)驅(qū)動UI更新:通過狀態(tài)變量的改變,來驅(qū)動UI的刷新。
以下示例展示了自定義組件的基本用法。
@Component
struct HelloComponent {
@State message: string = 'Hello, World!';
build() {
// HelloComponent自定義組件組合系統(tǒng)組件Row和Text
Row() {
Text(this.message)
.onClick(() => {
// 狀態(tài)變量message的改變驅(qū)動UI刷新,UI從'Hello, World!'刷新為'Hello, ArkUI!'
this.message = 'Hello, ArkUI!';
})
}
}
}
HelloComponent可以在其他自定義組件中的build()函數(shù)中多次創(chuàng)建,實現(xiàn)自定義組件的重用。
@Entry
@Component
struct ParentComponent {
build() {
Column() {
Text('ArkUI message')
HelloComponent({ message: 'Hello, World!' });
Divider()
HelloComponent({ message: '你好!' });
}
}
}
自定義組件的基本結(jié)構(gòu)
- struct:自定義組件基于struct實現(xiàn),struct + 自定義組件名 + {...}的組合構(gòu)成自定義組件,不能有繼承關系。對于struct的實例化,可以省略new。
說明
自定義組件名、類名、函數(shù)名不能和系統(tǒng)組件名相同。
- @Component:@Component裝飾器僅能裝飾struct關鍵字聲明的數(shù)據(jù)結(jié)構(gòu)。struct被@Component裝飾后具備組件化的能力,需要實現(xiàn)build方法描述UI,一個struct只能被一個@Component裝飾。
說明
從API version 9開始,該裝飾器支持在ArkTS卡片中使用。
@Component
struct MyComponent {
}
- build()函數(shù):build()函數(shù)用于定義自定義組件的聲明式UI描述,自定義組件必須定義build()函數(shù)。
@Component
struct MyComponent {
build() {
}
}
- @Entry:@Entry裝飾的自定義組件將作為UI頁面的入口。在單個UI頁面中,最多可以使用@Entry裝飾一個自定義組件。
說明
從API version 9開始,該裝飾器支持在ArkTS卡片中使用。
@Entry
@Component
struct MyComponent {
}
成員函數(shù)/變量
自定義組件除了必須要實現(xiàn)build()函數(shù)外,還可以實現(xiàn)其他成員函數(shù),成員函數(shù)具有以下約束:
- 不支持靜態(tài)函數(shù)。
- 成員函數(shù)的訪問始終是私有的。
自定義組件可以包含成員變量,成員變量具有以下約束:
- 不支持靜態(tài)成員變量。
- 所有成員變量都是私有的,變量的訪問規(guī)則與成員函數(shù)的訪問規(guī)則相同。
- 自定義組件的成員變量本地初始化有些是可選的,有些是必選的。具體是否需要本地初始化,是否需要從父組件通過參數(shù)傳遞初始化子組件的成員變量。
自定義組件的參數(shù)規(guī)定
從上文的示例中了解到,可以在build方法或者@Builder裝飾的函數(shù)里創(chuàng)建自定義組件,在創(chuàng)建的過程中,參數(shù)可以被提供給組件。
@Component
struct MyComponent {
private countDownFrom: number = 0;
private color: Color = Color.Blue;
build() {
}
}
@Entry
@Component
struct ParentComponent {
private someColor: Color = Color.Pink;
build() {
Column() {
// 創(chuàng)建MyComponent實例,并將創(chuàng)建MyComponent成員變量countDownFrom初始化為10,將成員變量color初始化為this.someColor
MyComponent({ countDownFrom: 10, color: this.someColor })
}
}
}
build()函數(shù)
所有聲明在build()函數(shù)的語言,我們統(tǒng)稱為UI描述語言,UI描述語言需要遵循以下規(guī)則:
- @Entry裝飾的自定義組件,其build()函數(shù)下的根節(jié)點唯一且必要,且必須為容器組件,其中ForEach禁止作為根節(jié)點。
@Component裝飾的自定義組件,其build()函數(shù)下的根節(jié)點唯一且必要,可以為非容器組件,其中ForEach禁止作為根節(jié)點。
@Entry
@Component
struct MyComponent {
build() {
// 根節(jié)點唯一且必要,必須為容器組件
Row() {
ChildComponent()
}
}
}
@Component
struct ChildComponent {
build() {
// 根節(jié)點唯一且必要,可為非容器組件
Image('test.jpg')
}
}
- 不允許聲明本地變量,反例如下。
build() {
// 反例:不允許聲明本地變量
let a: number = 1;
}
- 不允許在UI描述里直接使用console.info,但允許在方法或者函數(shù)里使用,反例如下。
build() {
// 反例:不允許console.info
console.info('print debug log');
}
- 不允許創(chuàng)建本地的作用域,反例如下。
build() {
// 反例:不允許本地作用域
{
...
}
}
- 不允許調(diào)用除了被@Builder裝飾以外的方法,允許系統(tǒng)組件的參數(shù)是TS方法的返回值。
@Component
struct ParentComponent {
doSomeCalculations() {
}
calcTextValue(): string {
return 'Hello World';
}
@Builder doSomeRender() {
Text(`Hello World`)
}
build() {
Column() {
// 反例:不能調(diào)用沒有用@Builder裝飾的方法
this.doSomeCalculations();
// 正例:可以調(diào)用
this.doSomeRender();
// 正例:參數(shù)可以為調(diào)用TS方法的返回值
Text(this.calcTextValue())
}
}
}
- 不允許switch語法,如果需要使用條件判斷,請使用if。反例如下。
build() {
Column() {
// 反例:不允許使用switch語法
switch (expression) {
case 1:
Text('...')
break;
case 2:
Image('...')
break;
default:
Text('...')
break;
}
}
}
- 不允許使用表達式,反例如下。
build() {
Column() {
// 反例:不允許使用表達式
(this.aVar > 10) ? Text('...') : Image('...')
}
}
自定義組件通用樣式
自定義組件通過“.”鏈式調(diào)用的形式設置通用樣式。
@Component
struct MyComponent2 {
build() {
Button(`Hello World`)
}
}
@Entry
@Component
struct MyComponent {
build() {
Row() {
MyComponent2()
.width(200)
.height(300)
.backgroundColor(Color.Red)
}
}
}
說明
ArkUI給自定義組件設置樣式時,相當于給MyComponent2套了一個不可見的容器組件,而這些樣式是設置在容器組件上的,而非直接設置給MyComponent2的Button組件。通過渲染結(jié)果我們可以很清楚的看到,背景顏色紅色并沒有直接生效在Button上,而是生效在Button所處的開發(fā)者不可見的容器組件上。
自定義屬性方法
自定義組件不支持提供自定義屬性方法,可以借助類似Controller控制器能力,提供自定義接口。
// 自定義controller
export class MyComponentController {
item: MyComponent = null;
setItem(item: MyComponent) {
this.item = item;
}
changeText(value: string) {
this.item.value = value;
}
}
// 自定義組件
@Component
export default struct MyComponent {
public controller: MyComponentController = null;
@State value: string = 'Hello World';
build() {
Column() {
Text(this.value)
.fontSize(50)
}
}
aboutToAppear() {
if (this.controller)
this.controller.setItem(this); // 綁定controller
}
}
// 使用處邏輯
@Entry
@Component
struct StyleExample {
controller = new MyComponentController();
build() {
Column() {
MyComponent({ controller: this.controller })
}
.onClick(() => {
this.controller.changeText('Text');
})
}
}
在上面的示例中:文章來源:http://www.zghlxwxcb.cn/news/detail-764958.html
- 通過子組件MyComponent的aboutToAppear方法,把當前的this指針傳遞給MyComponentController的item成員變量。
- 在StyleExample父組件中持有controller實例,調(diào)用controller的changeText方法,即相當于通過controller持有的MyComponent子組件的this指針,改變MyComponent的狀態(tài)變量value的值。
通過controller的封裝,MyComponent對外暴露了changeText的接口,所有持有controller的實例都可以通過調(diào)用changeText接口,改變MyComponent的狀態(tài)變量value的值。文章來源地址http://www.zghlxwxcb.cn/news/detail-764958.html
到了這里,關于HarmonyOS學習路之方舟開發(fā)框架—學習ArkTS語言(基本語法 二)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!