1、自定義構(gòu)建函數(shù)
1.1、構(gòu)建函數(shù)- @Builder
??如果你不想在直接抽象組件,ArkUI還提供了一種更輕量的UI元素復(fù)用機(jī)制 @Builder,可以將重復(fù)使用的UI元素抽象成一個方法,在 build 方法里調(diào)用。稱之為自定義構(gòu)建函數(shù)
- 用法- 使用@Builder修飾符修飾
1.1.1、全局自定義 @Builder function name () {}
??全局自定義函數(shù)指在struct外面的函數(shù)
@Builder
function getCellContent(leftTitle: string, rightValue: string) { // 全局自定義函數(shù)帶function
Row() {
Row() {
Text(leftTitle)
Text(rightValue)
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
.padding({
left: 15,
right: 15
})
.borderRadius(8)
.height(40)
.backgroundColor(Color.White)
}.padding({
left: 10,
right: 10
})
}
在組件中使用
Column({space:10}) {
getCellContent("時間", "2023-12-12")
getCellContent("位置", "上海")
getCellContent("愛好", "乒乓")
}
全局自定義函數(shù)的問題
● 全局的自定義構(gòu)建函數(shù)可以被整個應(yīng)用獲?。ㄏ乱淮捎?當(dāng)前4.0暫不支持),不允許使用this和bind方法。
● 如果不涉及組件狀態(tài)變化,建議使用全局的自定義構(gòu)建方法。
● 補(bǔ)一句-如果數(shù)據(jù)是響應(yīng)式的-此時該函數(shù)不會自動渲染-哪怕是全局自定義函數(shù),不可被其他文件引用
將數(shù)據(jù)聲明為State響應(yīng)式數(shù)據(jù)
class CardClass {
time: string = ""
location: string = ""
type: string = ""
}
@State formData: CardClass = {
time: "2023-12-12",
location: '回龍觀',
type: '漏油'
}
傳遞數(shù)據(jù),綁定為對應(yīng)字段
Column({ space: 10 }) {
getCellContent("異常時間", this.formData.time)
getCellContent("異常位置", this.formData.location)
getCellContent("異常類型", this.formData.type)
Button("修改數(shù)據(jù)").onClick(() => {
this.formData.location = "望京"
})
}
.width('100%')
??我們發(fā)現(xiàn),點擊修飾是沒有任何反應(yīng)的,說明此時即使你用了State,但是此時的全局builder依然不更新
1.1.2、組件內(nèi)定義- 語法 @Builder name () {}
@Entry
@Component
struct BuilderCase {
@Builder
getCellContent(leftTitle: string, rightValue: string) { // 組件內(nèi)自定義函數(shù)不帶function
}
}
調(diào)用
this.getCellContent("異常時間", this.formData.time)
??調(diào)用多了this,其他和全局屬性一樣,沒有任何變化,此時我們發(fā)現(xiàn)修改數(shù)據(jù)依然沒有任何變化
??注意: 我們剛剛傳過去的是類型,string是一個基礎(chǔ)數(shù)據(jù)類型,它是按值傳遞的,不具備響應(yīng)式更新的特點
總結(jié)
- 全局Builder函數(shù)和組件Builder構(gòu)建函數(shù)可以實現(xiàn)一種輕量級的UI復(fù)用,
- 區(qū)別: 全局自定義構(gòu)建函數(shù)不允許使用this,bind,它適合一種純渲染的UI結(jié)構(gòu);組件內(nèi)自定義Builder可以實現(xiàn)this調(diào)用
1.2、參數(shù)傳遞
自定義構(gòu)建函數(shù)的參數(shù)傳遞有按值傳遞和按引用傳遞兩種,均需遵守以下規(guī)則:
- 參數(shù)的類型必須與參數(shù)聲明的類型一致,不允許undefined、null和返回undefined、null的表達(dá)式。
- 在自定義構(gòu)建函數(shù)內(nèi)部,不允許改變參數(shù)值。如果需要改變參數(shù)值,且同步回調(diào)用點,建議使用@Link。
- @Builder內(nèi)UI語法遵循UI語法規(guī)則。
- 只有傳入一個參數(shù),且參數(shù)需要直接傳入對象字面量才會按引用傳遞該參數(shù),其余傳遞方式均為按值傳遞。
?1)、使用了string這種基礎(chǔ)數(shù)據(jù)類型,即使它屬于用State修飾的變量,也不會引起UI的變化
?2)、按引用傳遞參數(shù)時,傳遞的參數(shù)可為狀態(tài)變量,且狀態(tài)變量的改變會引起@Builder方法內(nèi)的UI刷新。ArkUI提供$$作為按引用傳遞參數(shù)的范式。
ABuilder( $$ : 類型 );
函數(shù)名稱( obj: 類型 );
?3)、也就是我們需要在builder中傳入一個對象, 該對象使用$$(可使用其他字符)的符號來修飾,此時數(shù)據(jù)具備響應(yīng)式了
@Entry
@Component
struct BuilderCase {
@State formData: CardClass = { // state修飾的狀態(tài)變量
time: "2023-12-12",
location: '回龍觀',
type: '漏油'
}
@Builder
getCellContent($$: CellParams) { // 傳入一個對象,$$可以為任意字符
Row() {
Row() {
Text($$.leftTitle)
Text($$.rightValue)
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
.padding({
left: 15,
right: 15
})
.borderRadius(8)
.height(40)
.backgroundColor(Color.White)
}.padding({
left: 10,
right: 10
})
}
build() {
Row() {
Column() {
Column({ space: 10 }) {
this.getCellContent({ leftTitle: '異常時間', rightValue: this.formData.time }) // 傳入一個對象,且有state修飾符修飾的變量
this.getCellContent({ leftTitle: '異常位置', rightValue: this.formData.location }) // 傳入一個對象,且有state修飾符修飾的變量
this.getCellContent({ leftTitle: '異常類型', rightValue: this.formData.type })
}
.width('100%')
Button("修改數(shù)據(jù)").onClick(() => {
this.formData.location = "望京" // 修改state修改是的對象的屬性,可以導(dǎo)致UI更新
})
}
.width('100%')
}
.height('100%')
.backgroundColor('#ccc')
}
}
● 使用 @Builder 復(fù)用邏輯的時候,支持傳參可以更靈活的渲染UI
● 參數(shù)可以使用狀態(tài)數(shù)據(jù),通過對象的方式傳入 @Builder