本文分享自華為雲社群《深入理解ArkTs中的AppStorage和LocalStorage》,作者:檸檬味擁抱 。
ARKTS(Ark TypeScript)是HarmonyOS應用框架的一部分,提供了一種靈活而強大的狀態管理機制。在ARKTS中,AppStorage和LocalStorage是兩個關鍵的概念,它們分別用於應用級和頁面級的狀態共享。透過深入瞭解這兩個特性,我們可以更好地理解如何在應用程式中管理和共享狀態資料。
AppStorage:全域性狀態的中樞
AppStorage是應用啟動時建立的單例,其主要目的是提供應用級別的全域性狀態儲存。這些狀態資料在整個應用中都是可訪問的,它們在應用執行期間保留其屬性。透過唯一的鍵字串,我們可以訪問AppStorage中的屬性,實現全域性狀態的共享。
與UI的互動是透過@StorageProp和@StorageLink實現的。@StorageProp用於建立單向資料同步,允許本地的修改發生,但不會同步回AppStorage中。而@StorageLink建立雙向資料同步,使得本地的修改會被同步到AppStorage中,反之亦然。這為應用的狀態管理提供了極大的靈活性。
// 示例程式碼 @StorageProp('exampleKey') exampleValue: number = 42; @StorageLink('anotherKey') anotherValue: string = 'Hello, ARKTS!';
透過上述程式碼,我們在AppStorage中建立了兩個屬性:‘exampleKey’和’anotherKey’,並透過@StorageProp和@StorageLink將它們與UI元件中的變數建立了關聯。這種關聯使得應用狀態和UI的變化能夠實時同步,實現了高效的狀態管理。
LocalStorage:頁面級的資料共享
與AppStorage不同,LocalStorage是頁面級的資料共享機制。通常應用於頁面內的資料共享,它提供了一種簡單而有效的方式,使頁面元件能夠共享狀態而不需要顯式的傳遞資料。在頁面級別,LocalStorage的作用類似於元件內部的全域性變數,方便在頁面內各個元件之間進行狀態傳遞。
// 示例程式碼 let pageStorage: LocalStorage = new LocalStorage(); pageStorage.set('pageTitle', 'My Awesome Page'); let title: string = pageStorage.get('pageTitle');
在上述程式碼中,我們使用LocalStorage建立了一個頁面級的儲存空間,並在其中儲存了頁面的標題。透過get和set方法,我們能夠在頁面內的任何元件中訪問和修改這些資料,實現了頁面級別的狀態共享。
與PersistentStorage和Environment的協作
AppStorage不僅可以和UI元件同步,還可以與PersistentStorage(持久化資料儲存)和Environment(環境變數)協作,形成一個完整的狀態管理體系。透過持久化資料的儲存和環境變數的設定,我們能夠實現資料的長期儲存和應用環境的靈活配置。
需要注意的是,使用AppStorage與PersistentStorage時,需要注意呼叫順序。在AppStorage中建立屬性後,呼叫PersistentStorage.persistProp()時會使用AppStorage中已經存在的值,並覆蓋PersistentStorage中的同名屬性。因此,建議在使用PersistentStorage前訪問AppStorage中的屬性。
// 示例程式碼 AppStorage.setOrCreate('appTheme', 'light'); PersistentStorage.persistProp('appTheme');
從應用邏輯和UI內部使用儲存
在應用邏輯中,可以透過AppStorage的靜態方法來進行狀態的設定和獲取。而在UI內部,透過@StorageProp和@StorageLink裝飾器,可以將元件的屬性與AppStorage中的屬性進行繫結,實現資料的雙向同步。
// 示例程式碼 @StorageProp('counter') counter: number = 0; @StorageLink('userToken') userToken: string = '';
上述程式碼中,counter和userToken分別與AppStorage中的’counter’和’userToken’屬性建立了關聯。這樣,在UI中修改這些屬性時,AppStorage中的資料會同步更新,反之亦然。
不建議藉助@StorageLink的雙向同步實現事件通知
雖然@StorageLink提供了雙向同步的機制,但不建議將其用於事件通知。因為AppStorage是與UI相關的資料儲存,修改會觸發UI的重新整理,而事件通知的成本相對較大。推薦使用emitter方式來實現事件通知,提高程式碼的可讀性和效能。
// 不推薦的示例程式碼 @StorageLink('tapIndex') tapIndex: number = -1; // 推薦的示例程式碼 import emitter from '@ohos.events.emitter'; emitter.on('onTapIndexChange', (data) => { // 處理事件通知 });
透過emitter方式,我們可以更靈活地實現事件的訂閱和釋出,避免不必要的UI重新整理,提高應用的效能。
示例演練
為了更好地理解AppStorage和LocalStorage的使用,讓我們透過一個簡單的示例演練來展示它們的實際應用。
// 示例演練程式碼 // AppStorage示例 @StorageProp('appCounter') appCounter: number = 0; // LocalStorage示例 let pageStorage: LocalStorage = new LocalStorage(); @Component struct App { build() { Column() { // 顯示AppStorage中的計數器值 Text(`App Counter: ${this.appCounter}`); // 顯示LocalStorage中的頁面標題 Text(`Page Title: ${pageStorage.get('pageTitle')}`); // 按鈕,點選時AppStorage計數器加1 Button('Increment App Counter') .onClick(() => { this.appCounter += 1; }); // 按鈕,點選時修改LocalStorage中的頁面標題 Button('Change Page Title') .onClick(() => { pageStorage.set('pageTitle', 'New Page Title'); }); } } } // 在另一個元件中使用@StorageLink @StorageLink('appCounter') counterFromLink: number = 0; @Component struct AnotherComponent { build() { Column() { // 顯示透過@StorageLink關聯的AppStorage計數器值 Text(`Counter from Link: ${this.counterFromLink}`); } } }
上述程式碼中,我們建立了一個App元件,其中使用了@StorageProp和LocalStorage,演示瞭如何在應用級別(AppStorage)和頁面級別(LocalStorage)進行狀態管理。另外,透過在另一個元件中使用@StorageLink,展示瞭如何在不同元件之間實現狀態的雙向同步。
限制條件和最佳實踐
在使用AppStorage和LocalStorage時,我們需要注意一些限制條件和最佳實踐:
- 呼叫順序問題: 在AppStorage中建立屬性後,呼叫PersistentStorage.persistProp()介面時,會使用在AppStorage中已經存在的值,並覆蓋PersistentStorage中的同名屬性。因此,建議在使用PersistentStorage前訪問AppStorage中的屬性。
- 屬性命名注意事項: 如果在AppStorage中已經建立屬性後,再呼叫Environment.envProp()建立同名的屬性,會呼叫失敗。因此,建議AppStorage中的屬性不要使用Environment預置環境變數名。
- 狀態裝飾器和事件通知: 狀態裝飾器裝飾的變數改變會引起UI的渲染更新。如果改變的變數不是用於UI更新,只是用於訊息傳遞,推薦使用emitter方式來實現事件通知,以減小UI重新整理的成本。
- 合理使用@StorageProp和@StorageLink: 在應用邏輯中,可以透過AppStorage的靜態方法來進行狀態的設定和獲取。而在UI內部,透過@StorageProp和@StorageLink裝飾器,可以將元件的屬性與AppStorage中的屬性進行繫結,實現資料的雙向同步。但要注意不要濫用雙向同步機制,以避免不必要的效能開銷。
- 事件通知的最佳化: 不建議藉助@StorageLink的雙向同步機制實現事件通知。由於AppStorage是與UI相關的資料儲存,修改會觸發UI的重新整理,而事件通知的成本相對較大。推薦使用emitter方式來實現事件通知,提高程式碼的可讀性和效能。
結語
透過深入理解ARKTS中的AppStorage和LocalStorage,我們能夠更好地利用這兩個特性進行應用狀態的管理和共享。合理使用這些工具,可以提高程式碼的可維護性和效能,使得開發更加高效。在實際開發中,根據具體需求和場景選擇合適的狀態管理方式,將有助於構建更健壯、可擴充套件的HarmonyOS應用。
ARKTS中的AppStorage和LocalStorage為開發者提供了強大的狀態管理工具,使得應用程式能夠高效地共享和管理狀態資料。透過與PersistentStorage和Environment的協作,可以實現更全面的狀態管理和資料持久化。在開發過程中,合理使用@StorageProp和@StorageLink等裝飾器,以及emitter方式,能夠更好地組織和維護應用的狀態邏輯。