移動端開發(fā),最重要的一點就是數(shù)據(jù)的處理,并且正確的顯示渲染UI。
變量在頁面和組件、組件和組件之間有時候并不能實時共享,而有時候,又不需要太多的作用域(節(jié)省資源),作用就需要根據(jù)不同場景,設置不同狀態(tài)的變量。
官方文檔
一、狀態(tài)管理概述
在聲明式UI編程框架中,UI是程序狀態(tài)的運行結果,用戶構建了一個UI模型,其中應用的運行時的狀態(tài)是參數(shù)。當參數(shù)改變時,UI作為返回結果,也將進行對應的改變。這些運行時的狀態(tài)變化所帶來的UI的重新渲染,在ArkUI中統(tǒng)稱為狀態(tài)管理機制。
簡單理解就是:當變量改變時,相關的UI也能跟著改變,為達到這個目的,引入了狀態(tài)變量
自定義組件擁有變量,變量必須被裝飾器裝飾才可以成為狀態(tài)變量,狀態(tài)變量的改變會引起UI的渲染刷新。如果不使用狀態(tài)變量,UI只能在初始化時渲染,后續(xù)將不會再刷新。 下圖展示了State和View(UI)之間的關系。
因為
常規(guī)變量:沒有狀態(tài)的變量,通常應用于輔助計算。它的改變永遠不會引起UI的刷新。
所以引入狀態(tài)變量
狀態(tài)變量:被狀態(tài)裝飾器裝飾的變量,改變會引起UI的渲染更新。
State:狀態(tài),一般指的是裝飾器裝飾的數(shù)據(jù)。用戶通過觸發(fā)組件的事件方法,改變狀態(tài)數(shù)據(jù)。狀態(tài)數(shù)據(jù)的改變,引起UI的重新渲染。
二、 狀態(tài)管理總覽 管理應用擁有的狀態(tài)
1.管理組件擁有的狀態(tài)
Components級別的狀態(tài)管理
裝飾器 | 描述 |
---|---|
@State | @State裝飾的變量擁有其所屬組件的狀態(tài),可以作為其子組件單向和雙向同步的數(shù)據(jù)源。當其數(shù)值改變時,會引起相關組件的渲染刷新。 |
@Prop | @Prop裝飾的變量可以和父組件建立單向同步關系,@Prop裝飾的變量是可變的,但修改不會同步回父組件。 |
@Link | @Link裝飾的變量和父組件構建雙向同步關系的狀態(tài)變量,父組件會接受來自@Link裝飾的變量的修改的同步,父組件的更新也會同步給@Link裝飾的變量。 |
@Provide/@Consume | @Provide/@Consume裝飾的變量用于跨組件層級(多層組件)同步狀態(tài)變量,可以不需要通過參數(shù)命名機制傳遞,通過alias(別名)或者屬性名綁定。 |
@Observed | @Observed裝飾class,需要觀察多層嵌套場景的class需要被@Observed裝飾。單獨使用@Observed沒有任何作用,需要和@ObjectLink、@Prop連用。 |
@ObjectLink | @ObjectLink裝飾的變量接收@Observed裝飾的class的實例,應用于觀察多層嵌套場景,和父組件的數(shù)據(jù)源構建雙向同步。 |
2.管理應用擁有的狀態(tài)
- AppStorage是應用程序中的一個特殊的單例LocalStorage對象,是應用級的數(shù)據(jù)庫,和進程綁定,通過@StorageProp和@StorageLink裝飾器可以和組件聯(lián)動。
- AppStorage是應用狀態(tài)的“中樞”,需要和組件(UI)交互的數(shù)據(jù)存入AppStorage,比如持久化數(shù)據(jù)PersistentStorage和環(huán)境變量Environment。UI再通過AppStorage提供的裝飾器或者API接口,訪問這些數(shù)據(jù);
- 框架還提供了LocalStorage,AppStorage是LocalStorage特殊的單例。LocalStorage是應用程序聲明的應用狀態(tài)的內(nèi)存“數(shù)據(jù)庫”,通常用于頁面級的狀態(tài)共享,通過@LocalStorageProp和@LocalStorageLink裝飾器可以和UI聯(lián)動。
三、狀態(tài)介紹
1、@State裝飾器:組件內(nèi)狀態(tài)
@State裝飾器:組件內(nèi)狀態(tài)
示例
@Entry
@Component
struct MyComponent {
@State count: number = 0;
build() {
Button(`click times: ${this.count}`)
.onClick(() => {
this.count += 1;
})
}
}
2、@Prop裝飾器:父子單向同步
@Prop裝飾器:父子單向同步
示例
- @Prop customCounter沒有本地初始化,所以需要父組件提供數(shù)據(jù)源去初始化@Prop,并當父組件的數(shù)據(jù)源變化時,@Prop也將被更新;
- @Prop customCounter2有本地初始化,在這種情況下,@Prop依舊允許但非強制父組件同步數(shù)據(jù)源給@Prop。
@Component
struct MyComponent {
@Prop customCounter: number;
@Prop customCounter2: number = 5;
build() {
Column() {
Row() {
Text(`From Main: ${this.customCounter}`).width(90).height(40).fontColor('#FF0010')
}
Row() {
Button('Click to change locally !').width(180).height(60).margin({ top: 10 })
.onClick(() => {
this.customCounter2++
})
}.height(100).width(180)
Row() {
Text(`Custom Local: ${this.customCounter2}`).width(90).height(40).fontColor('#FF0010')
}
}
}
}
@Entry
@Component
struct MainProgram {
@State mainCounter: number = 10;
build() {
Column() {
Row() {
Column() {
Button('Click to change number').width(480).height(60).margin({ top: 10, bottom: 10 })
.onClick(() => {
this.mainCounter++
})
}
}
Row() {
Column()
// customCounter必須從父組件初始化,因為MyComponent的customCounter成員變量缺少本地初始化;此處,customCounter2可以不做初始化。
MyComponent({ customCounter: this.mainCounter })
// customCounter2也可以從父組件初始化,父組件初始化的值會覆蓋子組件customCounter2的本地初始化的值
MyComponent({ customCounter: this.mainCounter, customCounter2: this.mainCounter })
}
}
}
}
3、@Link裝飾器:父子雙向同步
@Link裝飾器:父子雙向同步
示例解釋:
父組件定了了兩個變量(@State greenButtonState,@State yellowButtonProp),傳遞給子組件,子組件使用@Link裝飾器關聯(lián),當這兩個變量在父組件改變時,子組件里面的值也跟著改變從而改變UI,同時由于@Link的關系,這兩個參數(shù)在子組件里面改變了,也會夫組件里的變量也會跟著改變
class GreenButtonState {
width: number = 0;
constructor(width: number) {
this.width = width;
}
}
@Component
struct GreenButton {
@Link greenButtonState: GreenButtonState;
build() {
Button('Green Button')
.width(this.greenButtonState.width)
.height(150.0)
.backgroundColor('#00ff00')
.onClick(() => {
if (this.greenButtonState.width < 700) {
// 更新class的屬性,變化可以被觀察到同步回父組件
this.greenButtonState.width += 125;
} else {
// 更新class,變化可以被觀察到同步回父組件
this.greenButtonState = new GreenButtonState(100);
}
})
}
}
@Component
struct YellowButton {
@Link yellowButtonState: number;
build() {
Button('Yellow Button')
.width(this.yellowButtonState)
.height(150.0)
.backgroundColor('#ffff00')
.onClick(() => {
// 子組件的簡單類型可以同步回父組件
this.yellowButtonState += 50.0;
})
}
}
@Entry
@Component
struct ShufflingContainer {
@State greenButtonState: GreenButtonState = new GreenButtonState(300);
@State yellowButtonProp: number = 100;
build() {
Column() {
// 簡單類型從父組件@State向子組件@Link數(shù)據(jù)同步
Button('Parent View: Set yellowButton')
.onClick(() => {
this.yellowButtonProp = (this.yellowButtonProp < 700) ? this.yellowButtonProp + 100 : 100;
})
// class類型從父組件@State向子組件@Link數(shù)據(jù)同步
Button('Parent View: Set GreenButton')
.onClick(() => {
this.greenButtonState.width = (this.greenButtonState.width < 700) ? this.greenButtonState.width + 100 : 100;
})
// class類型初始化@Link
GreenButton({ greenButtonState: $greenButtonState })
// 簡單類型初始化@Link
YellowButton({ yellowButtonState: $yellowButtonProp })
}
}
}
4、@Provide裝飾器和@Consume裝飾器:與后代組件雙向同步
@Provide裝飾器和@Consume裝飾器:與后代組件雙向同步
示例:
在下面的示例是與后代組件雙向同步狀態(tài)@Provide和@Consume場景。當分別點擊CompA和CompD組件內(nèi)Button時,reviewVotes 的更改會雙向同步在CompA和CompD中。
@Component
struct CompD {
// @Consume裝飾的變量通過相同的屬性名綁定其祖先組件CompA內(nèi)的@Provide裝飾的變量
@Consume reviewVotes: number;
build() {
Column() {
Text(`reviewVotes(${this.reviewVotes})`)
Button(`reviewVotes(${this.reviewVotes}), give +1`)
.onClick(() => this.reviewVotes += 1)
}
.width('50%')
}
}
@Component
struct CompC {
build() {
Row({ space: 5 }) {
CompD()
CompD()
}
}
}
@Component
struct CompB {
build() {
CompC()
}
}
@Entry
@Component
struct CompA {
// @Provide裝飾的變量reviewVotes由入口組件CompA提供其后代組件
@Provide reviewVotes: number = 0;
build() {
Column() {
Button(`reviewVotes(${this.reviewVotes}), give +1`)
.onClick(() => this.reviewVotes += 1)
CompB()
}
}
}
5、@Observed裝飾器和@ObjectLink裝飾器:嵌套類對象屬性變化
@Observed裝飾器和@ObjectLink裝飾器:嵌套類對象屬性變化
6、LocalStorage:頁面級UI狀態(tài)存儲
LocalStorage:頁面級UI狀態(tài)存儲
7、AppStorage:應用全局的UI狀態(tài)存儲
AppStorage:應用全局的UI狀態(tài)存儲
8、PersistentStorage:持久化存儲UI狀態(tài)
PersistentStorage:持久化存儲UI狀態(tài)
9、Environment:設備環(huán)境查詢
Environment:設備環(huán)境查詢
10、@Watch裝飾器:狀態(tài)變量更改通知
@Watch裝飾器:狀態(tài)變量更改通知文章來源:http://www.zghlxwxcb.cn/news/detail-777190.html
11、$$語法:內(nèi)置組件雙向同步
$$語法:內(nèi)置組件雙向同步文章來源地址http://www.zghlxwxcb.cn/news/detail-777190.html
到了這里,關于HarmonyOS 應用開發(fā)學習筆記 狀態(tài)管理概述的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!