构建可扩展的状态系统:基于 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 的开发旅程中提供一些思路和帮助!

相关推荐
zhanshuo4 小时前
ArkTS 模块通信全解析:用事件总线实现页面消息联动
harmonyos
codefish7989 小时前
鸿蒙开发学习之路:从入门到实践的全面指南
harmonyos
yrjw15 小时前
一款基于react-native harmonyOS 封装的【文档】文件预览查看开源库(基于Harmony 原生文件预览服务进行封装)
harmonyos
搜狐技术产品小编20231 天前
搜狐新闻直播间适配HarmonyOs实现点赞动画
华为·harmonyos
zhanshuo2 天前
ArkUI 玩转水平滑动视图:超全实战教程与项目应用解析
harmonyos·arkui
zhanshuo2 天前
ArkUI Canvas 实战:快速绘制柱状图图表组件
harmonyos·arkui
zhanshuo2 天前
手把手教你用 ArkUI 写出高性能分页列表:List + onScroll 实战解析
harmonyos
zhanshuo2 天前
深入解析 ArkUI 触摸事件机制:从点击到滑动的开发全流程
harmonyos
i仙银2 天前
鸿蒙沙箱浏览器 - SandboxFinder
app·harmonyos