前言欢迎加入开源鸿蒙跨平台社区https://openharmonycrossplatform.csdn.net状态管理是 ArkUI 声明式 UI 范式的核心State和Prop是最基础的两个装饰器。小分享 App 的 BottomTabBar 通过State和Prop实现 Tab 高亮联动是理解状态管理的经典案例。本篇详细讲解状态的定义、传递和响应式更新。详细 API 可参考 HarmonyOS 状态管理官方文档。一、State 装饰器1.1 基本用法State用于声明组件内部状态状态变化时自动触发 UI 重建Component struct HomePage { State currentTab: number 0 build() { Column() { // 内容区域 Scroll() { /* ... */ } .layoutWeight(1) // 底部导航栏 BottomTabBar({ currentIndex: this.currentTab }) } } }1.2 State 特性特性说明示例响应式值变化时自动触发 UI 更新this.currentTab 1→ UI 刷新私有仅当前组件可访问子组件无法直接修改初始化必须赋初始值State count: number 0类型支持基本类型、对象、数组State items: Arraystring []提示State 变量变化时整个组件的build方法会重新执行性能敏感场景需谨慎。二、Prop 装饰器2.1 基本用法Prop用于父组件向子组件传递数据实现单向数据流Component export struct BottomTabBar { Prop currentIndex: number 0 // 默认值 0 Prop title: string }2.2 父子传递父组件通过属性语法传递数据给子组件// 父组件HomePage State currentTab: number 0 BottomTabBar({ currentIndex: this.currentTab }) // 子组件BottomTabBar Prop currentIndex: number 02.3 Prop 特性特性说明单向数据流父→子子修改不影响父默认值可设置默认值组件独立使用时生效响应式父组件变化时子组件自动更新类型支持支持基本类型、对象、数组三、Tab 高亮联动实现3.1 完整数据流HomePage 组件 State currentTab: number 0 │ ├─ onClick → 改变 currentTab │ └─ BottomTabBar({ currentIndex: this.currentTab }) │ Prop currentIndex: number 0 │ └─ Text(item.label) .fontColor(index this.currentIndex ? #F5A623 : #999999)3.2 高亮逻辑Text(item.label) .fontSize(10) .fontColor(index this.currentIndex ? #F5A623 : #999999)3.3 高亮状态对比状态条件文字颜色图标颜色选中index currentIndex#F5A623(橙色)正常显示未选中index ! currentIndex#999999(灰色)正常显示四、State 与 Prop 对比4.1 对比表格特性StateProp所属当前组件当前组件数据来源自身初始化父组件传入修改影响触发自身 UI 更新不影响父组件默认值必须初始化可选生命周期组件生命周期同组件生命周期作用域组件内组件内4.2 代码块对比// State 示例组件内私有状态 Component struct Counter { State count: number 0 build() { Button(Count: ${this.count}) .onClick(() { this.count }) } } // Prop 示例父组件传值 Component struct Display { Prop value: number 0 build() { Text(Value: ${this.value}) } }五、State 在编辑器中的使用5.1 文字编辑器状态Component struct TextEditPage { State textContent: string 生活的美好在于分享 State fontSize: number 16 State fontColor: string #333333 State isBold: boolean false State textAlign: TextAlign TextAlign.Start }5.2 双向绑定TextArea({ text: this.textContent, placeholder: 输入内容... }) .onChange((value: string) { this.textContent value // 状态变化 → UI 自动更新 })六、State 在筛选器中的使用6.1 滤镜选中态Component struct ImageEditPage { State selectedFilter: number 0 build() { ForEach(this.filters, (item: FilterItem, index: number) { Column() .border({ width: this.selectedFilter index ? 2 : 0, color: #F5A623 }) .onClick(() { this.selectedFilter index // 选中态变化 }) }) } }6.2 分类 Tab 选中态Component struct TemplateSelectPage { State selectedCategory: number 0 build() { ForEach(this.categories, (item: string, index: number) { Text(item) .fontColor(this.selectedCategory index ? #F5A623 : #666666) .fontWeight(this.selectedCategory index ? FontWeight.Bold : FontWeight.Normal) .onClick(() { this.selectedCategory index }) }) } }七、State 不可变数据原则7.1 对象类型// ❌ 直接修改对象属性不会触发 UI 更新 this.item.title 新标题 // ✅ 创建新对象 this.item { ...this.item, title: 新标题 }7.2 数组类型// ❌ 直接修改数组元素不会触发更新 this.categories[0].label 新文字 // ✅ 创建新数组 this.categories this.categories.map((item, index) { if (index 0) { return { ...item, label: 新文字 } } return item })7.3 代码块示例不可变操作// 使用展开运算符实现不可变 const updated [...this.items, newItem] this.items updated // 使用 filter 删除 this.items this.items.filter(i i.id ! removeId) // 使用 map 更新 this.items this.items.map(i { if (i.id targetId) { return { ...i, title: 新标题 } } return i })八、常见问题8.1 问题 1State 修改后 UI 不更新原因对于对象或数组类型直接修改内部属性不会触发响应式更新。解决始终创建新的对象或数组。8.2 问题 2Prop 默认值不生效原因父组件未传值时使用默认值父组件传undefined时不会回退到默认值。解决在父组件中始终提供有效的值。九、核心知识点9.1 状态管理要点State组件内私有状态变化触发 UI 更新Prop父→子单向数据传递不可变数据原则创建新对象/数组替代直接修改State支持基本类型、对象、数组9.2 实战建议状态变化遵循不可变原则Prop默认值确保组件独立可用复杂状态使用ObservedObjectLink总结本文详细讲解了 HarmonyOS 状态管理中State和Prop装饰器的使用结合小分享 App 的 BottomTabBar 高亮联动、文字编辑器状态、滤镜选中态等实际案例演示了状态的定义、传递和响应式更新。下一篇我们将深入 TextEditPage 文字编辑器的实现。附录状态管理实战对比不同状态管理方案的适用场景方案适用场景复杂度推荐度State组件内私有状态低⭐⭐⭐⭐⭐Prop父→子单向传参低⭐⭐⭐⭐⭐Link父子双向同步中⭐⭐⭐⭐Provide/Consume跨层级共享中⭐⭐⭐⭐AppStorage应用级全局状态中⭐⭐⭐⭐LocalStorage页面级局部状态中⭐⭐⭐Observed/ObjectLink复杂对象监听高⭐⭐⭐小分享 App 中的状态管理实践页面使用的装饰器管理的数据HomePageStatecurrentTab 选中 TabBottomTabBarPropcurrentIndex 高亮索引TextEditPageStatetextContent, fontSizeImageEditPageStateselectedFilter 滤镜选中LinkEditPageStatelinkTitle, showDescriptionTemplateSelectPageStateselectedCategory 分类选中FavoritesPageStateselectedTab 分类选中提示在小分享 App 中所有页面级状态均使用 State 管理组件间传参使用 Prop没有使用全局状态管理。这种方案在页面数量较少时足够简洁高效。状态管理最佳实践总结状态最小化原则只在需要驱动 UI 更新的数据上使用 State普通变量用常规声明单向数据流优先使用 Prop 单向传递避免 Link 造成的双向耦合不可变更新对象和数组始终创建新副本不要直接修改原数据状态提升多个子组件需要共享的状态提升到最近的共同父组件中管理局部优先能用 State 解决的问题不用全局状态方案代码块示例完整的状态管理流程// 1. 父组件定义状态 Entry Component struct ParentPage { State activeIndex: number 0 build() { Column() { // 2. 通过 Prop 传递给子组件 ChildComponent({ index: this.activeIndex }) // 3. 通过回调修改状态 Button(切换).onClick(() { this.activeIndex 1 // 触发 UI 更新 }) } } } // 4. 子组件接收状态 Component struct ChildComponent { Prop index: number 0 build() { Text(当前索引: ${this.index}) } }调试技巧// 使用 Watch 监听状态变化 State Watch(onStateChange) count: number 0 onStateChange(): void { console.info(count changed to: this.count) }性能注意事项避免在 State 中存储大量数据如大型数组会导致每次变化时全量对比频繁变化的状态如动画帧建议使用State配合animateTo方法对象类型的 State 变化时只有引用变化才会触发 UI 更新内部属性变化不触发与 Vue/React 状态管理对比特性ArkTS StateVue ref()React useState响应式自动追踪自动追踪显式 setter对象变更需创建新引用深层响应式需创建新引用数组变更需创建新数组支持索引变更需创建新数组装饰器Stateref/reactiveuseState学习成本低低中提示ArkTS 的 State 在使用上与 React 的 useState 类似都需要遵循不可变数据原则。这与 Vue 的响应式系统支持深层监听有所不同。 如果这篇文章对你有帮助欢迎点赞、收藏⭐、关注你的支持是我持续创作的动力