【OpenHarmony/HarmonyOs 】ArkTS 项目中的状态管理:@State、@Link、LocalStorage 实战
【OpenHarmony/HarmonyOs 】ArkTS 项目中的状态管理:@State、@Link、LocalStorage 实战
ArkUI 开发中,状态管理是最容易出问题的地方之一。页面为什么不刷新?父子组件为什么不同步?深色模式为什么切了但颜色没变?本文结合 政治视界 项目,系统整理 @State、@Link、@Prop、LocalStorage 在真实项目中的用法 ⚙️
一、状态管理的基本分层
项目中状态大致分为四类:
- 页面内部状态:按钮按压、弹窗显示、当前索引;
- 父子共享状态:当前 Tab、首页刷新信号;
- 全局状态:安全区、深色模式;
- 持久化业务状态:错题、学习统计、设置。
不同状态要用不同工具,不要所有东西都塞进一个全局对象。
二、@State:页面内部响应式状态
题库页面中:
@State currentQuestionIndex: number = 0;
@State selectedAnswer: string[] = [];
@State showResult: boolean = false;
@State isCorrect: boolean = false;
这些状态只属于 QuizPage,所以用 @State 最合适。用户选择答案后,selectedAnswer 变化,选项 UI 自动更新;提交后 showResult 变化,结果区域显示。
三、@Link:父子组件双向绑定
首页需要修改当前 Tab,从推荐题跳到题库。因此 HomePage 接收父组件传入的 currentTab:
@Component
export struct HomePage {
@Link currentTab: number;
}
父组件中这样传入:
HomePage({ currentTab: $currentTab, refreshSignal: $homePageRefresh })
首页点击推荐题:
goToPractice(questionId: number): void {
this.dataManager.setQuizJumpQuestion(questionId);
this.currentTab = 3;
}
@Link 适合这种父子之间需要双向同步的场景。
四、@Prop:单向传值
有些子组件只需要接收值,不需要修改父组件状态,就用 @Prop。例如统计页中的分类统计行:
@Component
struct CategoryStatItem {
@Prop category: string = '';
@Prop total: number = 0;
@Prop correct: number = 0;
}
注意项目规范里也强调:@Prop 不要写可选参数,给默认值更稳。
五、LocalStorage:全局轻量状态
安全区和深色模式属于全局状态。项目中创建了 appLocalStorage:
const storage: LocalStorage = new LocalStorage();
storage.setOrCreate(SAFE_AREA_TOP_VP_KEY, 0);
storage.setOrCreate(SAFE_AREA_BOTTOM_VP_KEY, 0);
storage.setOrCreate(STORAGE_KEY_DARK_MODE, false);
页面通过:
@LocalStorageProp(SAFE_AREA_TOP_VP_KEY) safeTopVp: number = 0;
@LocalStorageProp(SAFE_AREA_BOTTOM_VP_KEY) safeBottomVp: number = 0;
读取安全区高度。这让所有页面都能共享窗口避让区数据。
六、@LocalStorageLink:全局状态双向更新
主题刷新令牌使用:
@LocalStorageLink(THEME_REFRESH_KEY)
private themeRefresh: number = 0;
切换主题时:
this.themeRefresh = this.themeRefresh + 1;
它不仅修改本页面状态,也更新 LocalStorage 中的值,从而让其他绑定者感知变化。
七、@Watch:监听状态变化
主页面监听深色模式变化:
@Watch('onDarkModeChange')
@LocalStorageProp(DARK_MODE_KEY) isDarkMode: boolean = false;
onDarkModeChange(): void {
AppTheme.isDarkMode = this.isDarkMode;
AppTheme.themeRefreshToken = this.themeRefresh;
}
@Watch 很适合做“状态变化后的副作用”,比如同步主题管理器。
八、持久化状态不要直接放 UI
错题、学习统计、设置这些数据最终要保存到 Preferences,所以项目通过 DataManager 管理:
private dataManager: DataManager = DataManager.getInstance();
initStats(): void {
this.completedQuestions = this.dataManager.getCompletedQuestions();
this.correctRate = this.dataManager.getCorrectRate();
}
页面只把读取结果放入 @State 展示,不直接操作 Preferences。
九、常见坑
- 修改普通变量不会触发 UI 更新;
- 静态变量变化不一定触发页面刷新;
- 子组件要修改父组件状态时必须用
@Link; - 列表数据变化最好赋新数组;
- 复杂逻辑不要写在
build()里; ForEach要提供稳定 key。
十、结语
政治视界中状态管理比较清晰:页面状态用 @State,父子同步用 @Link,只读传值用 @Prop,安全区和主题用 LocalStorage,业务持久化交给 DataManager。
ArkUI 状态管理的核心不是记住所有装饰器,而是判断“这个状态属于谁、谁会修改、是否需要持久化”。这个问题想清楚了,页面就会稳定很多 ✅


更多推荐



所有评论(0)