构建可扩展的状态系统:基于 ArkTS 的模块化状态管理设计与实现

摘要

在 HarmonyOS 的日常开发中,很多人都会遇到一个问题:多个页面之间的数据状态如何共享?尤其是在组件结构越来越复杂的场景下,如果还用传统方式来传值,不仅代码混乱,维护也很吃力。

为了解决这个问题,本文将介绍一种用 ArkTS 实现的"模块化状态管理"方式。它的思路有点类似于 React 中的 Redux,通过创建一个单独的状态模块,把所有共享状态集中管理,再在各个页面中引用它,从而实现状态同步更新。

引言

随着应用体量越来越大,一个页面一个状态的写法已经越来越难以满足业务需求了。例如:首页有一个计数器,设置页也需要读取和修改这个值;再比如,有些全局配置比如暗黑模式、用户登录信息等,全 app 都要用。

这种时候,模块化状态管理就非常有用了。它的好处是:

  • 状态集中管理
  • 页面之间不需要一层层传参
  • 状态变化可控、可追踪
  • 更易测试与维护

而 ArkTS 原生就支持单例和模块导入的机制,所以在 HarmonyOS 中实现模块化状态管理其实并不复杂。

用 ArkTS 实现模块化状态管理

创建一个状态模块(StateManager)

我们先来看一个最简单的状态管理模块,只包含一个全局的计数器:

ts 复制代码
// 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。

ts 复制代码
// 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 里有多个页面(比如首页、购物车页、商品详情页),都需要显示购物车里的商品数量。

状态模块

ts 复制代码
// 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;
  }
}

首页展示购物车数量

ts 复制代码
// 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);
  }
}

购物车页面清空功能

ts 复制代码
// 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:全局用户信息管理

比如你有个用户模块,登录成功后需要把用户信息存下来,后续其他页面都能用。

ts 复制代码
// 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 的开发旅程中提供一些思路和帮助!

相关推荐
whysqwhw2 小时前
鸿蒙分布式投屏
harmonyos
whysqwhw3 小时前
鸿蒙AVSession Kit
harmonyos
whysqwhw5 小时前
鸿蒙各种生命周期
harmonyos
whysqwhw6 小时前
鸿蒙音频编码
harmonyos
whysqwhw6 小时前
鸿蒙音频解码
harmonyos
whysqwhw6 小时前
鸿蒙视频解码
harmonyos
whysqwhw6 小时前
鸿蒙视频编码
harmonyos
ajassi20006 小时前
开源 Arkts 鸿蒙应用 开发(十八)通讯--Ble低功耗蓝牙服务器
华为·开源·harmonyos
前端世界7 小时前
在鸿蒙应用中快速接入地图功能:从配置到实战案例全解析
华为·harmonyos
江拥羡橙9 小时前
【基础-判断】HarmonyOS提供了基础的应用加固安全能力,包括混淆、加密和代码签名能力
安全·华为·typescript·harmonyos