掌握HarmonyOS框架的ArkTs如何管理和共享狀態資料

華為雲開發者聯盟發表於2023-11-30

本文分享自華為雲社群《深入理解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方式來實現事件通知,提高程式碼的可讀性和效能。

cke_137.png

cke_138.png

// 不推薦的示例程式碼

@StorageLink('tapIndex')

tapIndex: number = -1;

// 推薦的示例程式碼

import emitter from '@ohos.events.emitter';

emitter.on('onTapIndexChange', (data) => {

// 處理事件通知

});

透過emitter方式,我們可以更靈活地實現事件的訂閱和釋出,避免不必要的UI重新整理,提高應用的效能。

cke_139.png

示例演練

為了更好地理解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時,我們需要注意一些限制條件和最佳實踐:

  1. 呼叫順序問題: 在AppStorage中建立屬性後,呼叫PersistentStorage.persistProp()介面時,會使用在AppStorage中已經存在的值,並覆蓋PersistentStorage中的同名屬性。因此,建議在使用PersistentStorage前訪問AppStorage中的屬性。
  2. 屬性命名注意事項: 如果在AppStorage中已經建立屬性後,再呼叫Environment.envProp()建立同名的屬性,會呼叫失敗。因此,建議AppStorage中的屬性不要使用Environment預置環境變數名。
  3. 狀態裝飾器和事件通知: 狀態裝飾器裝飾的變數改變會引起UI的渲染更新。如果改變的變數不是用於UI更新,只是用於訊息傳遞,推薦使用emitter方式來實現事件通知,以減小UI重新整理的成本。
  4. 合理使用@StorageProp和@StorageLink: 在應用邏輯中,可以透過AppStorage的靜態方法來進行狀態的設定和獲取。而在UI內部,透過@StorageProp和@StorageLink裝飾器,可以將元件的屬性與AppStorage中的屬性進行繫結,實現資料的雙向同步。但要注意不要濫用雙向同步機制,以避免不必要的效能開銷。
  5. 事件通知的最佳化: 不建議藉助@StorageLink的雙向同步機制實現事件通知。由於AppStorage是與UI相關的資料儲存,修改會觸發UI的重新整理,而事件通知的成本相對較大。推薦使用emitter方式來實現事件通知,提高程式碼的可讀性和效能。

結語

透過深入理解ARKTS中的AppStorage和LocalStorage,我們能夠更好地利用這兩個特性進行應用狀態的管理和共享。合理使用這些工具,可以提高程式碼的可維護性和效能,使得開發更加高效。在實際開發中,根據具體需求和場景選擇合適的狀態管理方式,將有助於構建更健壯、可擴充套件的HarmonyOS應用。

ARKTS中的AppStorage和LocalStorage為開發者提供了強大的狀態管理工具,使得應用程式能夠高效地共享和管理狀態資料。透過與PersistentStorage和Environment的協作,可以實現更全面的狀態管理和資料持久化。在開發過程中,合理使用@StorageProp和@StorageLink等裝飾器,以及emitter方式,能夠更好地組織和維護應用的狀態邏輯。

 

點選關注,第一時間瞭解華為雲新鮮技術~

 

相關文章