摘要
在 HarmonyOS 的日常開發中,很多人都會遇到一個問題:多個頁面之間的數據狀態如何共享?尤其是在組件結構越來越復雜的場景下,如果還用傳統方式來傳值,不僅代碼混亂,維護也很吃力。
為了解決這個問題,本文將介紹一種用 ArkTS 實現的“模塊化狀態管理”方式。它的思路有點類似于 React 中的 Redux,通過創建一個單獨的狀態模塊,把所有共享狀態集中管理,再在各個頁面中引用它,從而實現狀態同步更新。
引言
隨著應用體量越來越大,一個頁面一個狀態的寫法已經越來越難以滿足業務需求了。例如:首頁有一個計數器,設置頁也需要讀取和修改這個值;再比如,有些全局配置比如暗黑模式、用戶登錄信息等,全 app 都要用。
這種時候,模塊化狀態管理就非常有用了。它的好處是:
- 狀態集中管理
- 頁面之間不需要一層層傳參
- 狀態變化可控、可追蹤
- 更易測試與維護
而 ArkTS 原生就支持單例和模塊導入的機制,所以在 HarmonyOS 中實現模塊化狀態管理其實并不復雜。
用 ArkTS 實現模塊化狀態管理
創建一個狀態模塊(StateManager)
我們先來看一個最簡單的狀態管理模塊,只包含一個全局的計數器:
// StateManager.ts
export class StateManager {private static instance: StateManager;public count: number = 0;private constructor() {}static getInstance() {if (!StateManager.instance) {StateManager.instance = new StateManager();}return StateManager.instance;}
}
這個模塊用了經典的“單例模式”,也就是只創建一個實例,在整個 app 中共享。任何頁面只要調用 StateManager.getInstance()
,就能拿到這個共享狀態。
在頁面中引用這個狀態模塊
下面我們寫一個頁面,展示這個 count 值,并且點擊按鈕讓它 +1。
// MainPage.ets
import { StateManager } from './StateManager';@Entry
@Component
struct MainPage {private stateManager = StateManager.getInstance();build() {Column() {Text(`Count: ${this.stateManager.count}`).fontSize(20);Button('Increment').onClick(() => {this.stateManager.count++;});}.padding(20);}
}
現在我們打開這個頁面,點擊按鈕,每點一次,count
就加一。
模塊化狀態在實際場景中的使用案例
案例 1:多頁面共享的購物車數量
假設我們在商城 app 里有多個頁面(比如首頁、購物車頁、商品詳情頁),都需要顯示購物車里的商品數量。
狀態模塊
// CartState.ts
export class CartState {private static instance: CartState;public itemCount: number = 0;private constructor() {}static getInstance() {if (!CartState.instance) {CartState.instance = new CartState();}return CartState.instance;}addItem() {this.itemCount++;}clearCart() {this.itemCount = 0;}
}
首頁展示購物車數量
// HomePage.ets
import { CartState } from './CartState';@Component
struct HomePage {private cartState = CartState.getInstance();build() {Row() {Text(`購物車商品數量: ${this.cartState.itemCount}`)Button('添加商品').onClick(() => {this.cartState.addItem();});}.padding(20);}
}
購物車頁面清空功能
// CartPage.ets
import { CartState } from './CartState';@Component
struct CartPage {private cartState = CartState.getInstance();build() {Column() {Text(`當前數量: ${this.cartState.itemCount}`)Button('清空購物車').onClick(() => {this.cartState.clearCart();});}}
}
這樣,兩個頁面共享同一個 CartState
實例,更新狀態時,頁面數據也會同步。
案例 2:全局用戶信息管理
比如你有個用戶模塊,登錄成功后需要把用戶信息存下來,后續其他頁面都能用。
// UserState.ts
export class UserState {private static instance: UserState;public username: string = '';public isLoggedIn: boolean = false;private constructor() {}static getInstance() {if (!UserState.instance) {UserState.instance = new UserState();}return UserState.instance;}login(name: string) {this.username = name;this.isLoggedIn = true;}logout() {this.username = '';this.isLoggedIn = false;}
}
你可以在登錄頁使用 login(name)
方法,在設置頁調用 logout()
來退出登錄,并在其他頁面通過 isLoggedIn
來判斷用戶狀態。
QA 環節:開發中常遇到的問題
Q1:這個狀態會在頁面切換后丟失嗎?
不會。 因為用了單例模式,所以狀態是保存在內存里的,除非應用被殺掉或者你主動清空。
Q2:多個組件同時引用這個狀態,會沖突嗎?
不會沖突,但不會自動刷新。 如果你在頁面 A 修改了狀態,頁面 B 想實時感知,需要結合 @Observed
或自定義通知機制(比如事件總線)來實現響應式更新。
Q3:這個方式適合大型項目嗎?
適合做輕量的狀態管理。 如果項目非常復雜、狀態特別多、需要響應式更新的場景比較多,建議結合 ArkTS 的 @Observed
, @State
, @Provide
等裝飾器,或者結合事件總線、信號機制使用。
總結
模塊化狀態管理在 ArkTS 中是非常實用的一種方案,尤其適合開發多人協作或頁面組件繁多的中大型項目。通過單例模式封裝狀態模塊,我們可以實現:
- 頁面之間的狀態共享
- 狀態統一管理,易于維護
- 代碼結構清晰,易擴展
當然,如果你的應用場景對狀態變化的實時性要求更高,推薦結合 ArkTS 的響應式裝飾器或事件總線來做更進一步的擴展。
未來你也可以在這個基礎上加上本地緩存(比如存入 Preferences
),或者結合 @Observed
屬性做組件刷新。希望這篇文章能為你在 ArkTS 的開發旅程中提供一些思路和幫助!