本文轉(zhuǎn)載自《#2023 盲盒+碼 #?OpenHarmony 應(yīng)用 ArkUI?狀態(tài)管理開發(fā)范例》,作者:zhushangyuan_
本文根據(jù)橘子購物應(yīng)用,實現(xiàn) ArkUI 中的狀態(tài)管理。
在聲明式 UI 編程框架中,UI 是程序狀態(tài)的運行結(jié)果,用戶構(gòu)建了一個 UI 模型,其中應(yīng)用的運行時的狀態(tài)是參數(shù)。當(dāng)參數(shù)改變時,UI 作為返回結(jié)果,也將進(jìn)行對應(yīng)的改變。這些運行時的狀態(tài)變化所帶來的 UI 的重新渲染,在 ArkUI 中統(tǒng)稱為狀態(tài)管理機(jī)制。
自定義組件擁有變量,變量必須被裝飾器裝飾才可以成為狀態(tài)變量,狀態(tài)變量的改變會引起 UI 的渲染刷新。如果不使用狀態(tài)變量,UI 只能在初始化時渲染,后續(xù)將不會再刷新。?下圖展示了 State 和 View(UI)之間的關(guān)系。

管理組件擁有的狀態(tài)
@State 裝飾器:組件內(nèi)狀態(tài)
@State 裝飾的變量,或稱為狀態(tài)變量,一旦變量擁有了狀態(tài)屬性,就和自定義組件的渲染綁定起來。當(dāng)狀態(tài)改變時,UI 會發(fā)生對應(yīng)的渲染改變。
在狀態(tài)變量相關(guān)裝飾器中,@State 是最基礎(chǔ)的,使變量擁有狀態(tài)屬性的裝飾器,它也是大部分狀態(tài)變量的數(shù)據(jù)源。
@link 裝飾器:父子雙向同步
子組件中被 @Link 裝飾的變量與其父組件中對應(yīng)的數(shù)據(jù)源建立雙向數(shù)據(jù)綁定。
@Link 裝飾的變量與其父組件中的數(shù)據(jù)源共享相同的值。
@Component
export struct DetailPage {
@State currentLocation: string = ''
}
在父組件 DetailPage 中聲明當(dāng)前定位 currentLocation 變量
Panel(this.isPanel)?{
????Location({?isPanel:?$isPanel,?currentLocation:?$currentLocation?})
}
將 currentLocation 變量傳給子組件 Location
@Component
export?struct?Location?{
??@Link?currentLocation:?string
}
子組件用 @Link 裝飾的 currentLocation 接收。
??@Builder?cityList(city:?any)?{
????if?(this.currentLocation?===?city.name)?{
??????List()?{
????????ForEach(city.city,?twoCity?=>?{
??????????ListItem()?{
????????????Column()?{
??????????????Text(`${twoCity}`)
????????????????.width('100%')
????????????????.height(30)
????????????????.fontSize(14)
????????????????.onClick(()?=>?{
??????????????????this.currentLocation?=?city.name?+?'/'?+?twoCity
????????????????})
????????????}
??????????}
????????})
??????}
??????.width('100%')
??????.divider({?strokeWidth:?2,?color:?$r('app.color.divider'),?startMargin:?0,?endMargin:?20?})
????}
??}
子組件中的 currentLocation 變量改變會同步父組件中的 currentLocation。
管理應(yīng)用擁有的狀態(tài)
AppStorage 是應(yīng)用全局的 UI 狀態(tài)存儲,是和應(yīng)用的進(jìn)程綁定的,由 UI 框架在應(yīng)用程序啟動時創(chuàng)建,為應(yīng)用程序 UI 狀態(tài)屬性提供中央存儲。
和 LocalStorage 不同的是,LocalStorage 是頁面級的,通常應(yīng)用于頁面內(nèi)的數(shù)據(jù)共享。而對于 AppStorage,是應(yīng)用級的全局狀態(tài)共享。AppStorage 使用場景和相關(guān)的裝飾器:@StorageProp 和 @StorageLink
@StorageProp
@StorageProp(key)是和 AppStorage 中 key 對應(yīng)的屬性建立單向數(shù)據(jù)同步,我們允許本地改變的發(fā)生,但是對于 @StorageProp,本地的修改永遠(yuǎn)不會同步回 AppStorage 中,相反,如果 AppStorage 給定 key 的屬性發(fā)生改變,改變會被同步給 @StorageProp,并覆蓋掉本地的修改。
@Entry
@Component
struct?HomePage {
@State curBp:?string?=?'md' //?curBp指當(dāng)前窗口斷點,sm代表小屏,md代表中屏,lg代表大屏
}
在Home.ets頁面中,用 @State 聲明當(dāng)前窗口類型:curBp 變量并賦初值為 md,代表中屏。
isBreakpointSM?=?(mediaQueryResult)?=> {
if?(mediaQueryResult.matches) {
??????this.curBp?=?'sm'
??????AppStorage.SetOrCreate('curBp',?this.curBp)
}
}
isBreakpointMD?=?(mediaQueryResult)?=> {
if?(mediaQueryResult.matches) {
??????this.curBp?=?'md'
??????AppStorage.SetOrCreate('curBp',?this.curBp)
}
}
isBreakpointLG?=?(mediaQueryResult)?=> {
if?(mediaQueryResult.matches) {
??????this.curBp?=?'lg'
??????AppStorage.SetOrCreate('curBp',?this.curBp)
}
}
根據(jù)屏幕尺寸,將 curBp 設(shè)置為相應(yīng)的值,并用 SetOrCreate()方法保存在 AppStorage 中。
在子組件 NavigationHomePage 中直接使用 curBp 變量
@Entry
@Component
export?struct?NavigationHomePage {
@StorageProp('curBp') curBp:?string?=?'sm'
}
curBp 是根據(jù)窗口的尺寸判斷的,是不能改變的,因此使用 @StorageProp(‘curBp’)與 AppStorage(‘curBp’)建立單向數(shù)據(jù)同步。
@StorageLink
@StorageLink(key)是和 AppStorage 中 key 對應(yīng)的屬性建立雙向數(shù)據(jù)同步:
1.? 本地修改發(fā)生,該修改會被同步回 AppStorage 中;
2.? AppStorage 中的修改發(fā)生后,該修改會被同步到所有綁定 AppStorage 對應(yīng) key 的屬性上,包括單向(@StorageProp 和通過 Prop 創(chuàng)建的單向綁定變量)、雙向(@StorageLink 和通過 Link 創(chuàng)建的雙向綁定變量)變量和其他實例(比如 PersistentStorage)。
@Entry
@Component
struct?HomePage {
@StorageLink('shoppingCartGoodsList')?shoppingCartGoodsList: { data: { id:?number?} }[]?=?[]
}
在Home.ets頁面中,用 @StorageLink 裝飾器定義 shoppingCartGoodsList,用于獲取全局的購物車商品列表。
this.emitterClass.setShoppingCartGoodsList((eventData)=>{
????this.shoppingCartGoodsList.push(eventData.data.id)
????AppStorage.SetOrCreate('shoppingCartGoodsList',?this.shoppingCartGoodsList)
})
使用 AppStorage.SetOrCreate(‘shoppingCartGoodsList’,?this.shoppingCartGoodsList)將購物車商品列表保存在 AppStorage 中。
因為購物車中的商品會聯(lián)動的變化,比如在商品的詳情頁將商品添加至購物車,在首頁也需要更新購物車信息,因此購物車商品列表采用 @StorageLink 裝飾器裝飾,與 AppStorage(‘shoppingCartGoodsList’)建立雙向同步。
運行測試效果
執(zhí)行以下命令,可以下載橘子購物應(yīng)用工程:文章來源:http://www.zghlxwxcb.cn/news/detail-689237.html
git?init
git?config?core.sparsecheckout?true
echo?code/Solutions/Shopping/OrangeShopping/?>?.git/info/sparse-checkout
git?remote?add?origin?https://gitee.com/openharmony/applications_app_samples.git
git?pull?origin?master
參考資料
橘子購物示例應(yīng)用文章來源地址http://www.zghlxwxcb.cn/news/detail-689237.html
到了這里,關(guān)于OpenHarmony 應(yīng)用 ArkUI 狀態(tài)管理開發(fā)范例的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!