ArkUI開發(fā)框架提供了多維度的狀態(tài)管理機(jī)制,和UI相關(guān)聯(lián)的數(shù)據(jù),不僅可以在組件內(nèi)使用,還可以在不同組件層級間傳遞,比如父子組件之間,爺孫組件之間等,也可以是全局范圍內(nèi)的傳遞,還可以是跨設(shè)備傳遞。另外,從數(shù)據(jù)的傳遞形式來看,可以分為只讀的單向傳遞和可變更的雙向傳遞。如下圖所示,開發(fā)框架提供了多種應(yīng)用程序狀態(tài)管理的能力。
@State修飾符
@State
裝飾的變量是組件內(nèi)部的狀態(tài)數(shù)據(jù),當(dāng)這些狀態(tài)數(shù)據(jù)被修改時,將會調(diào)用所在組件的 build()
方法刷新UI。 @State
狀態(tài)數(shù)據(jù)具有以下特征:
- 支持多種數(shù)據(jù)類型:允許
class
、number
、boolean
、string
強(qiáng)類型的按值和按引用類型。允許這些強(qiáng)類型構(gòu)成的數(shù)組,即Array
、Array
、Array
、Array
。不允許object
和any
。 - 內(nèi)部私有:標(biāo)記為
@State
的屬性是私有變量,只能在組件內(nèi)訪問。 - 支持多個實(shí)例:組件不同實(shí)例的內(nèi)部狀態(tài)數(shù)據(jù)獨(dú)立。
- 需要本地初始化:必須為所有
@State
變量分配初始值,將變量保持未初始化可能導(dǎo)致框架行為未定義,初始值需要是有意義的值,比如設(shè)置class
類型的值為null
就是無意義的,會導(dǎo)致編譯報(bào)錯。 - 創(chuàng)建自定義組件時支持通過狀態(tài)變量名設(shè)置初始值:在創(chuàng)建組件實(shí)例時,可以通過變量名顯式指定
@State
狀態(tài)屬性的初始值。
|
簡單樣例如下所示:
@Entry @Component struct ComponentTest {
@State date: string = "時間:" + new Date().getTime(); // data變化會觸發(fā)build方法執(zhí)行
build() {
Column({space: 10}) {
Text(`父組件【${this.date}】`) // 顯示時間
.fontSize(20)
.backgroundColor(Color.Pink)
Item() // 子組件
Item() // 子組件
Button('更新時間')
.onClick(() = > {
this.date = "時間:" + new Date().getTime(); // 點(diǎn)擊按鈕,date變化,會觸發(fā)build方法執(zhí)行
})
}
.width('100%')
.height('100%')
.padding(10)
}
}
// 自定義子組件
@Component struct Item {
@State time: string = "時間:" + new Date().getTime();
build() {
Text(`子組件【${this.time}】`)
.fontSize(20)
.backgroundColor(Color.Grey)
.onClick(() = > {
this.time = "時間:" + new Date().getTime(); // 點(diǎn)擊更新時間,執(zhí)行build方法
})
}
}
樣例運(yùn)行結(jié)果如下圖所示:
@Prop修飾符
開發(fā)應(yīng)用知識已更新[gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md
]參考前往。
@Prop
與 @State
有相同的語義,但初始化方式不同, @Prop
裝飾的變量可以和父組件的 @State
變量建立單向的數(shù)據(jù)綁定。即 @Prop
修飾的變量必須使用其父組件提供的 @State
變量進(jìn)行初始化,允許組件內(nèi)部修改 @Prop
變量值但更改不會通知給父組件。 @Prop
狀態(tài)數(shù)據(jù)具有以下特征:
支持簡單數(shù)據(jù)類型:僅支持
number
、string
、boolean
簡單類型;內(nèi)部私有:標(biāo)記為
@Prop
的屬性是私有變量,只能在組件內(nèi)訪問。支持多個實(shí)例:組件不同實(shí)例的內(nèi)部狀態(tài)數(shù)據(jù)獨(dú)立。
不支持內(nèi)部初始化:在創(chuàng)建組件的新實(shí)例時,必須將值傳遞給
@Prop
修飾的變量進(jìn)行初始化,不支持在組件內(nèi)部進(jìn)行初始化。
簡單樣例如下所示:@Entry @Component struct ComponentTest { @State date: string = "時間:" + new Date().getTime(); build() { Column({space: 10}) { Text(`父組件【${this.date}】`) .fontSize(20) .backgroundColor(Color.Pink) Item({time: this.date}) // 必須初始化子組件的time字段 Item({time: this.date}) // 必須初始化子組件的time字段 Button('更新時間') .onClick(() = > { this.date = "時間:" + new Date().getTime();// 父組件的更改影響子組件 }) } .width('100%') .height('100%') .padding(10) } } @Component struct Item { @Prop time: string; // 不允許本地初始化 build() { Text(`子組件【${this.time}】`) .fontSize(20) .backgroundColor(Color.Grey) .onClick(() = > { this.time = "時間:" + new Date().getTime(); // 子組件的更改不影響父組件 }) } }
樣例運(yùn)行結(jié)果如下圖所示:
@Link修飾符
@Link
與 @State
有相同的語義,但初始化方式不同, @Link
裝飾的變量可以和父組件的 @State
變量建立雙向的數(shù)據(jù)綁定。即 @Link
修飾的變量必須使用其父組件提供的 @State
變量進(jìn)行初始化,允許組件內(nèi)部修改 @Link
變量值且更改會通知給父組件。 @Link
狀態(tài)數(shù)據(jù)具有以下特征:
- 支持多種數(shù)據(jù)類型:
@Link
變量的值與@State
變量的類型相同,即class
、number
、string
、boolean
或這些類型的數(shù)組。 - 內(nèi)部私有:標(biāo)記為
@Link
的屬性是私有變量,只能在組件內(nèi)訪問。 - 支持多個實(shí)例:組件不同實(shí)例的內(nèi)部狀態(tài)數(shù)據(jù)獨(dú)立。
- 不支持內(nèi)部初始化:在創(chuàng)建組件的新實(shí)例時,必須將值傳遞給
@Link
修飾的變量進(jìn)行初始化,不支持在組件內(nèi)部進(jìn)行初始化。初始化使用$
符號,例如:$propertiesName。
樣例如下:
@Entry @Component struct ComponentTest {
@State date: string = "時間:" + new Date().getTime(); // 定義@State變量
build() {
Column({space: 10}) {
Text(`父組件【${this.date}】`)
.fontSize(20)
.backgroundColor(Color.Pink)
Item({time: $date}) // 初始化子組件time屬性使用$符號
Item({time: $date}) // 初始化子組件time屬性使用$符號
Button('更新時間')
.onClick(() = > {
this.date = "時間:" + new Date().getTime(); // 變更date,子組件的對應(yīng)屬性也變化
})
}
.width('100%')
.height('100%')
.padding(10)
}
}
@Component struct Item {
@Link time: string;
build() {
Text(`子組件【${this.time}】`)
.fontSize(20)
.backgroundColor(Color.Grey)
.onClick(() = > {
this.time = "時間:" + new Date().getTime(); // 變更time,父組件的對應(yīng)屬性也變化
})
}
}
樣例運(yùn)行結(jié)果如下圖所示:
@StorageLink修飾符
@StorageLink(key)
裝飾的變量是組件內(nèi)部的狀態(tài)數(shù)據(jù),當(dāng)這些狀態(tài)數(shù)據(jù)被修改時,將會調(diào)用所在組件的 build()
方法進(jìn)行UI刷新。組件通過使用 @StorageLink(key)
裝飾的狀態(tài)變量與 AppStorage
建立雙向數(shù)據(jù)綁定。當(dāng)創(chuàng)建包含 @StorageLink
的狀態(tài)變量的組件時,該狀態(tài)變量的值將使用 AppStorage
中的值進(jìn)行初始化,在UI組件中對 @StorageLink
的狀態(tài)變量所做的更改將同步到 AppStorage
,并從 AppStorage
同步到任何其他綁定實(shí)例中,如 PersistentStorage
或其他綁定的UI組件。 @StorageLink
狀態(tài)數(shù)據(jù)具有以下特征:
- 支持多種數(shù)據(jù)類型:支持的數(shù)據(jù)類型和
@State
一致且支持object
。 - 需要本地初始化:必須為所有
@StorageLink
變量分配初始值。 - 數(shù)據(jù)狀態(tài)全局化:使用
@StorageLink
修飾的數(shù)據(jù)變化后全局都會改變。 - 數(shù)據(jù)持久化:通過搭配
PersistentStorage
接口實(shí)現(xiàn)數(shù)據(jù)持久化。- 綁定數(shù)據(jù)
簡單樣例如下所示:@Entry @Component struct ComponentTest { @StorageLink('time') time: string = "1648643734154";// 使用StorageLink標(biāo)記并初始化 build() { Column({space: 10}) { Text(`父組件【${this.time}】`) // 使用time值 .fontSize(20) .backgroundColor(Color.Pink) Button('更新時間') .onClick(() = > { this.time = new Date().getTime().toString();// 更改time的值 }) } .width('100%') .height('100%') .padding(10) } }
- 綁定數(shù)據(jù)
運(yùn)行結(jié)果如下圖所示:
- **雙向綁定數(shù)據(jù)**
簡單樣例如下所示:
```
@Entry @Component struct ComponentTest {
@StorageLink('time') time1: string = "1648643734154";
@StorageLink('time') time2: string = "abcdefefwefwewee";
build() {
Column({space: 10}) {
Text(`父組件【${this.time1}】`)
.fontSize(20)
.backgroundColor(Color.Pink)
Item();
Item();
Button('更新時間')
.onClick(() = > {
this.time2 = new Date().getTime().toString();
})
}
.width('100%')
.height('100%')
.padding(10)
}
}
@Component struct Item {
@StorageLink('time') time: string = "OpenHarmony";
build() {
Text(`子組件【${this.time}】`)
.fontSize(20)
.backgroundColor(Color.Grey)
.onClick(() = > {
this.time = new Date().getTime().toString();
})
}
}
```
運(yùn)行結(jié)果如下圖所示:
- 頁面間數(shù)據(jù)綁定
簡單樣例如下圖所示:
// 第一個頁面
@Entry @Component struct ComponentTest {
@StorageLink('time') time1: string = "1648643734154";// 應(yīng)用key的值以首次初始化的值為準(zhǔn)
@StorageLink('time') time2: string = "abcdefefwefwewee";// time2以time1的值為準(zhǔn)
build() {
Column({space: 10}) {
Text(`父組件【${this.time1}】`)
.fontSize(20)
.backgroundColor(Color.Pink)
Item();// 使用自定義組件
Item();// 使用自定義組件
Button('更新時間')
.onClick(() = > {
this.time2 = new Date().getTime().toString();// 更改time2的值,所有使用key的頁面都會刷新
})
Button('跨頁面數(shù)據(jù)綁定')
.onClick(() = > {
router.push({uri: "pages/test/setting"})// 打開第二個頁面
})
}
.width('100%')
.height('100%')
.padding(10)
}
}
// 自定義個組件
@Component struct Item {
@StorageLink('time') time: string = "OpenHarmony";// time的值以key第一次出現(xiàn)的初始化為準(zhǔn)
build() {
Text(`子組件【${this.time}】`)
.fontSize(20)
.backgroundColor(Color.Grey)
.onClick(() = > {
this.time = new Date().getTime().toString();// 更改time的值,所有使用key的頁面都會刷新
})
}
}
// 第二個頁面
@Entry @Component struct Setting {
@StorageLink('time') tips: string = "我是第二個頁面"; // tips的值以'key'第一次出現(xiàn)的為準(zhǔn)
build() {
Column({space: 10}) {
Text(this.tips) // tips的值以'key'第一次出現(xiàn)的為準(zhǔn)
.fontSize(20)
.margin(20)
.onClick(() = > {
this.tips = "0000000000000" // 更改tips的值,所有使用key的頁面都會更新
})
Button('返回')
.onClick(() = > {
router.back()// 點(diǎn)擊返回,首頁的數(shù)據(jù)會更改
})
}
.width('100%')
.height('100%')
}
}
運(yùn)行結(jié)果如下圖所示:
- 持久化數(shù)據(jù)
@StorageLink
搭配 PersistentStorage
接口可以實(shí)現(xiàn)數(shù)據(jù)本地持久化,簡單樣例如下圖所示:
// 持久化存儲key并設(shè)置默認(rèn)值
PersistentStorage.PersistProp("time", "Hello, OpenHarmony")
@Entry @Component struct ComponentTest {
// 初始化time1,如果AppStorage
@StorageLink('time') time1: string = "1648643734154";
@StorageLink('time') time2: string = "OpenHarmony";
build() {
Column({space: 10}) {
Text(`父組件【${this.time1}】`)
.fontSize(20)
.backgroundColor(Color.Pink)
Item();
Item();
Button('更新時間')
.onClick(() = > {
this.time2 = new Date().getTime().toString();
})
Button('跨頁面數(shù)據(jù)綁定')
.onClick(() = > {
router.push({uri: "pages/test/setting"})
})
}
.width('100%')
.height('100%')
.padding(10)
}
}
// 自定義組件
@Component struct Item {
@StorageLink('time') time: string = "OpenHarmony";
build() {
Text(`子組件【${this.time}】`)
.fontSize(20)
.backgroundColor(Color.Grey)
.onClick(() = > {
this.time = new Date().getTime().toString();
})
}
}
運(yùn)行結(jié)果如下圖所示:
@Watch修飾符
@Watch
用來監(jiān)聽狀態(tài)變量的變化,當(dāng)它修飾的狀態(tài)變量發(fā)生變更時,回調(diào)相應(yīng)的方式,語法結(jié)構(gòu)為:
@State @Watch("function_name") count : number = 0;
上述語句表示:給狀態(tài)變量 count
增加一個 @Watch
裝飾器,通過 @Watch
注冊一個回調(diào)方法 function_name
, 當(dāng)狀態(tài)變量 count
被改變時, 觸發(fā) function_name
回調(diào)。
簡單樣例如下所示:
@Entry @Component struct WatchTest {
@State @Watch("onBasketUpdated") shopBasket: Array< number > = [7, 12, 47, 3];
@State totalPurchase: number = 0;
updateTotal(): number {
let sum = 0;
this.shopBasket.forEach((i) = > {
sum += i;
});
// 計(jì)算新的購物籃總價(jià)值,如果超過100RMB,則適用折扣
this.totalPurchase = (sum < 100) ? sum : 0.9 * sum;
return this.totalPurchase;
}
onBasketUpdated(propName: string): void {
this.updateTotal();
}
build() {
Column({space: 10}) {
Text(`${this.totalPurchase}`)
.fontSize(30)
Button("add to basket")
.onClick(() = > {
this.shopBasket.push(Math.round(100 * Math.random()))
})
}
.width("100%")
.height("100%")
.padding(10)
}
}
樣例運(yùn)行結(jié)果如下圖所示:
集合 shopBasket
是一個狀態(tài)變量,它被 @Watch
修飾符修飾并綁定了 onBasketUpdated()
方法回調(diào),當(dāng)點(diǎn)擊按鈕往 shopBasket
里添加數(shù)據(jù)時會觸發(fā) onBasketUpdated()
方法的調(diào)用,該方法里邊執(zhí)行了 totalPurchase
的數(shù)據(jù)計(jì)算,最后頁面刷新。
@Watch
裝飾器只能監(jiān)聽 @State
、 @Prop
、 @Link
、 @ObjectLink
、 @Provide
、 @Consume
、 @StorageProp
以及 @StorageLink
裝飾的變量。
小結(jié)
通過對ArkUI三種狀態(tài)管理的介紹,可以根據(jù)具體的業(yè)務(wù)場景選擇不同的狀態(tài)管理模式。
審核編輯 黃宇
-
鴻蒙
+關(guān)注
關(guān)注
59文章
2507瀏覽量
43765 -
HarmonyOS
+關(guān)注
關(guān)注
79文章
2052瀏覽量
32116 -
OpenHarmony
+關(guān)注
關(guān)注
26文章
3823瀏覽量
18126
發(fā)布評論請先 登錄
HarmonyOS開發(fā)實(shí)例:【分布式數(shù)據(jù)管理】

HarmonyOS開發(fā)必備知識
HarmonyOS應(yīng)用開發(fā)學(xué)習(xí)路線
HarmonyOS應(yīng)用開發(fā)NFC、藍(lán)牙、WLAN、網(wǎng)絡(luò)管理、電話服務(wù)資料
【HarmonyOS】應(yīng)用開發(fā)文檔
絕對干貨!HarmonyOS開發(fā)者日資料全公開,鴻蒙開發(fā)者都在看
【資料】華為HarmonyOS 音頻開發(fā)與管理指南
【資料合集】HarmonyOS應(yīng)用開發(fā)的學(xué)習(xí)路線
HarmonyOS/OpenHarmony應(yīng)用開發(fā)-FA模型綜述
HarmonyOS/OpenHarmony應(yīng)用開發(fā)-PageAbility開發(fā)體驗(yàn)
HarmonyOS資料下載專題

華為開發(fā)者分論壇HarmonyOS學(xué)生公開課-如何學(xué)習(xí)HarmonyOS應(yīng)用開發(fā)?

HarmonyOS開發(fā)—觀察蜂窩網(wǎng)絡(luò)狀態(tài)變化開發(fā)體驗(yàn)
面向HarmonyOS開發(fā)者的HarmonyOS 3.0 Beta介紹
【開發(fā)者說】HarmonyOS實(shí)踐之應(yīng)用狀態(tài)變量共享

評論