基礎語法
-
定義了聲明式UI描述;
-
自定義組件;
-
動態擴展UI元素的能力;
狀態管理
- 多維度裝填管理機制;
- 父子組件間
- 爺孫組件間
- 全局范圍內傳遞
- 跨設備傳遞
- 只讀的單向傳遞
- 可變的雙向傳遞
渲染控制
- UI描述:以聲明式的方式來描述UI的結構,例如build()方法中的代碼塊;
- 自定義組件:可復用的UI單元,可組合其他組件,如上述被@Component裝飾的struct Hello。、
- 系統組件:ArkUI框架中默認內置的基礎和容器組件。
自定義組件
-
可組合
-
可重用
-
數據驅動UI更新
自定義組件的基本結構
@Component struct HelloComponent {@State message: string = 'Hello, World!';build() {// HelloComponent自定義組件組合系統組件Row和TextRow() {Text(this.message).onClick(() => {// 狀態變量message的改變驅動UI刷新,UI從'Hello, World!'刷新為'Hello, ArkUI!'this.message = 'Hello, ArkUI!';})}} }
struct+自定義組件名+{…}
@Component裝飾器僅能裝飾struct關鍵字聲明的數據結構。
struct被@Component裝飾后具備組件化的能力,需要實現build方法描述UI。
@Component struct MyComponent {build() {} }
成員函數/變量
成員函數具有以下約束:
- 不支持靜態函數。
- 成員函數的訪問始終是私有的。
成員變量具有以下約束:
- 不支持靜態成員變量。
- 所有成員變量都是私有的,變量的訪問規則與成員函數的訪問規則相同。
- 自定義組件的成員變量本地初始化有些是可選的,有些是必選的。具體是否需要本地初始化,是否需要從父組件通過參數傳遞初始化子組件的成員變量,請參考狀態管理。
自定義組件的參數規定
@Component
struct MyComponent {private countDownFrom: number = 0;private color: Color = Color.Blue;build() {}
}@Entry
@Component
struct ParentComponent {private someColor: Color = Color.Pink;build() {Column() {// 創建MyComponent實例,并將創建MyComponent成員變量countDownFrom初始化為10,將成員變量color初始化為this.someColorMyComponent({ countDownFrom: 10, color: this.someColor })}}
}
build()函數
所有聲明在build()函數的語言,我們統稱為UI描述語言。
UI描述需要遵循以下規則:
@Entry裝飾的自定義組件,其build()函數下的根節點唯一且必要,且必須為容器組件,其中ForEach禁止作為根節點。
@Component裝飾的自定義組件,其build()函數下的根節點唯一且必要,可以為非容器組件,其中ForEach禁止作為根節點。
@Entry
@Component
struct MyComponent {build() {// 根節點唯一且必要,必須為容器組件Row() {ChildComponent() }}
}@Component
struct ChildComponent {build() {// 根節點唯一且必要,可為非容器組件Image('test.jpg')}
}
反例
build() {// 反例:不允許聲明本地變量let a: number = 1;
}
build() {// 反例:不允許聲明本地變量let a: number = 1;
}
不允許創建本地的作用域,反例如下
build() {// 反例:不允許本地作用域{...}
}
不允許調用除了被@Builder裝飾以外的方法,允許系統組件的參數是TS方法的返回值
@Component
struct ParentComponent {doSomeCalculations() {}calcTextValue(): string {return 'Hello World';}@Builder doSomeRender() {Text(`Hello World`)}build() {Column() {// 反例:不能調用沒有用@Builder裝飾的方法this.doSomeCalculations();// 正例:可以調用this.doSomeRender();// 正例:參數可以為調用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('...')}
}
自定義組件通用樣式
自定義組件通過“.”鏈式調用的形式設置通用樣式。
@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組件。通過渲染結果我們可以很清楚的看到,背景顏色紅色并沒有直接生效在Button上,而是生效在Button所處的開發者不可見的容器組件上。
頁面和自定義組件聲明周期
頁面
即應用的UI頁面。可以由一個或者多個自定義組件組成,
@Entry裝飾的自定義組件為頁面的入口組件,即頁面的根節點,一個頁面有且僅有一個@Entry
只有被@Entry裝飾的組件才可以調用頁面的聲明周期
-
onPageShow:頁面每次顯示時觸發。
-
onPageHide:頁面每次隱藏時觸發一次。
-
onBackPress:當用戶點擊返回按鈕時觸發。
-
aboutToAppear:組件即將出現時回調該接口,具體時機為在創建自定義組件的新實例后,在執行其build()函數之前執行。
-
aboutToDisappear:在自定義組件即將析構銷毀時執行。
// Index.ets
import router from '@ohos.router';@Entry
@Component
struct MyComponent {@State showChild: boolean = true;// 只有被@Entry裝飾的組件才可以調用頁面的生命周期onPageShow() {console.info('Index onPageShow');}// 只有被@Entry裝飾的組件才可以調用頁面的生命周期onPageHide() {console.info('Index onPageHide');}// 只有被@Entry裝飾的組件才可以調用頁面的生命周期onBackPress() {console.info('Index onBackPress');}// 組件生命周期aboutToAppear() {console.info('MyComponent aboutToAppear');}// 組件生命周期aboutToDisappear() {console.info('MyComponent aboutToDisappear');}build() {Column() {// this.showChild為true,創建Child子組件,執行Child aboutToAppearif (this.showChild) {Child()}// this.showChild為false,刪除Child子組件,執行Child aboutToDisappearButton('create or delete Child').onClick(() => {this.showChild = false;})// push到Page2頁面,執行onPageHideButton('push to next page').onClick(() => {router.pushUrl({ url: 'pages/Page2' });})}}
}@Component
struct Child {@State title: string = 'Hello World';// 組件生命周期aboutToDisappear() {console.info('[lifeCycle] Child aboutToDisappear')}// 組件生命周期aboutToAppear() {console.info('[lifeCycle] Child aboutToAppear')}build() {Text(this.title).fontSize(50).onClick(() => {this.title = 'Hello ArkUI';})}
}
@Builder裝飾器:自定義構建函數
@Builder所裝飾的函數遵循build()函數語法規則,開發者額可以將重復使用的UI元素抽象成一個方法,在build方法里調用。