HarmonyOS 状态管理:@State、@Prop、@Link、@Watch

HarmonyOS 状态管理:@State、@Prop、@Link、@Watch 适用版本HarmonyOS 6.1API 12及以上验证环境Pura 90 Pro 模拟器HarmonyOS 6.1.1API 24关键概念State、Prop、Link、Watch、单向数据流、双向绑定前言ArkUI 的状态管理基于响应式模型状态变量变化时UI 自动重新渲染关联的组件树。四个核心装饰器各有明确的数据流方向State私有→Prop单向→Link双向Watch负责观测变化并触发副作用。一、State — 组件私有状态Entry Component struct CounterPage { State count: number 0 // 私有只有本组件可读写 build() { Column({ space: 12 }) { Text(count ${this.count}) .fontSize(28).fontWeight(FontWeight.Bold) Row({ space: 12 }) { Button(-).onClick(() { this.count-- }) Button().onClick(() { this.count }) } } } }规则State变量变化 → ArkUI 自动重新渲染依赖它的 UI 区域外部组件不能直接读写State变量二、Prop — 父传子单向Component struct ChildDisplay { Prop count: number 0 // 父传来的副本子不能写回父 build() { Text(子组件显示: ${this.count}).fontColor(#666) } } // 父组件使用 ChildDisplay({ count: this.count }) // 父 count 变 → 子自动刷新规则父State变化 → 子Prop自动同步子组件修改Prop→ 只改子组件自己的副本不影响父三、Link — 双向绑定Component struct SharedCounter { Link sharedCount: number // 不设默认值从父引用 build() { Column({ space: 8 }) { Text(Link sharedCount ${this.sharedCount}) Button(子组件修改 Link 1) .onClick(() { this.sharedCount }) // 同步回父 } } } // 父组件 State sharedCount: number 0 // 使用时传 $引用符号 SharedCounter({ sharedCount: $sharedCount })规则Link不设默认值必须从父组件接收子修改Link→ 立即反映到父组件的State父 UI 同步刷新四、Watch — 状态变化监听Entry Component struct WatchDemo { Watch(onQueryChange) // watchTarget 变化时调用 onQueryChange State watchTarget: string State log: string[] [] onQueryChange(): void { // 副作用触发搜索、请求 API、发出事件等 this.log [...this.log.slice(-4), 变化 → ${this.watchTarget}] } build() { Column() { TextInput({ placeholder: 输入触发 Watch }) .onSubmit(() { this.watchTarget this.inputVal }) ForEach(this.log, (l: string) { Text(l).fontColor(#9b59b6) }) } } }规则Watch(方法名)声明在状态变量前当该变量变化时调用对应方法回调方法不接受参数用this.xxx读取新旧值适合触发 API 请求、日志记录等副作用五、四者对比装饰器数据流向修改权适用场景State内部只有自己组件私有计数器、开关、表单状态Prop父→子子仅本地展示父数据子不需要回写Link父↔子双方均可子组件需要修改父状态如弹窗关闭Watch观察任意 State无只监听状态变化时触发副作用模拟器运行截图初始状态交互后状态点击「」按钮增加计数、子组件修改 Link以及输入内容触发 Watch 后的显示状态。常见问题Q为什么修改 State 对象的属性如this.user.name xxx没有触发 UI 刷新AArkTS 的响应式检测粒度是赋值而不是属性修改。要触发刷新需要整体替换对象// ❌ 不触发刷新 this.user.name xxx // ✅ 触发刷新整体替换 const updated new User() updated.name xxx updated.age this.user.age this.user updatedQProp 可以是数组吗A可以。Prop list: string[] []有效但同样遵循单向规则子组件修改数组内容不会回写父组件。QWatch 的回调里可以再修改被 watch 的变量吗A可以但要避免无限循环修改触发回调回调再修改再触发回调…。通常在回调内加条件判断确保幂等。上一篇ArkUI 布局系统下一篇Provide/Consume 跨组件通信