鸿蒙_ArkUI自定义组件常用的三组状态装饰器

状态装饰器的作用是UI组件与变量绑定,当改变被状态装饰器装饰的变量的值,会同时引起UI更新。本文旨在系统比较鸿蒙ArkUI自定义组件开发中核心状态装饰器的用法,包括**@State与@Prop** 、@State与@Link 、**@Provide与@Consume,**帮助开发者学习组件的状态管理。

一、@State与@Prop

主要用于组件间单向数据传递,但作用域与可修改性存在根本差异。

@State:定义组件内部私有状态,仅当前组件可修改并触发刷新。必须初始化(如@State count: number = 0),适用于计数器、开关状态等内部管理。

@Prop:接收父组件传递的数据,支持父→子单向同步。子组件只读不可修改,父组件更新时自动刷新子组件。传递时直接赋值(如Child({propValue: this.parentState})),适用于静态数据展示。

TypeScript 复制代码
// 父组件:定义@State变量并传递
@Entry
@Component
struct ParentComponent {
  @State userName: string = "Tom" // 私有状态,可修改

  build() {
    Column() {
      Text("父组件: " + this.userName)
      Button("修改名称").onClick(() => {
        this.userName = "Jerry" // 触发自身刷新
      })
      // 向子组件传递@Prop (注意:需要传值,否则不会变)
      ChildComponent({ nameProp: this.userName })
    }
  }
}

// 子组件:接收@Prop,只读
@Component
struct ChildComponent {
  @Prop nameProp: string // 单向接收,不可修改,可以有初始值,也可以没有

  build() {
    Column() {
      Text("子组件展示: " + this.nameProp)
    }
  }
}

父组件按钮点击修改userName,子组件自动更新;子组件修改nameProp不会改变父组件。

二、@State与@Link

支持双向数据同步,但绑定机制与作用范围不同。

@State:同上,组件私有状态管理。

@Link:与父组件@State变量建立双向绑定,支持父子同步修改。子组件可读写并回传父组件。适用于表单输入等交互场景。

@State独立刷新,@Link依赖父组件引用;@Link禁止赋默认值。

TypeScript 复制代码
// 父组件:定义@State
@Entry
@Component
struct ParentComponent {
  @State count: number = 0 // 私有状态

  build() {
    Column() {
      Text("父组件计数: " + this.count)
      // 必须传值,不传会报错
      ChildComponent({ countLink: this.count })
    }
  }
}

// 子组件:接收@Link,可修改父状态
@Component
struct ChildComponent {
  @Link countLink: number // 双向绑定

  build() {
    Column() {
      Text("子组件计数: " + this.countLink)
      Button("子组件增加").onClick(() => {
        this.countLink += 1 // 修改同步至父组件
      })
    }
  }
}

子组件按钮点击增加countLink,父组件count同步更新并刷新UI;若父组件修改count,子组件亦同步刷新,双向同步。

三、@Provide与@Consume

用于跨层级组件状态共享,与@State/@Link相比,突破父子限制。

@Provide:在祖先组件提供状态,支持后代组件访问。需初始化(如@Provide() data: string = "Default"),通过别名或属性名绑定。

@Consume:在后代组件消费@Provide状态,支持双向同步。API 20+支持默认值(未匹配@Provide时生效)。

与@State/@Link相比:@Provide/@Consume可跨多层组件(如祖孙),无需逐层传递;@State/@Link仅限父子。@Consume修改自动触发祖先刷新。

TypeScript 复制代码
// 祖先组件:提供数据
@Entry
@Component
struct GrandParent {
  @Provide("sharedData") message: string = "Hello" // 提供状态,别名sharedData

  build() {
    Column() {
      Text("祖先: " + this.message)
      ParentComponent()
    }
  }
}

// 中间组件(无需传递参数)
@Component
struct ParentComponent {
  build() {
    Column() {
      ChildComponent()
    }
  }
}

// 后代组件:消费数据
@Component
struct ChildComponent {
  @Consume("sharedData") childMessage: string // 通过别名匹配

  build() {
    Column() {
      Text("后代: " + this.childMessage)
      Button("修改数据").onClick(() => {
        this.childMessage = "Updated" // 修改同步至祖先
      })
    }
  }
}

后代组件按钮点击修改childMessage,祖先组件message自动更新;祖先修改message,后代同步刷新,适用于全局配置或多级表单。如果变量名不一致可以取相同别名,变量名一致可以不取别名。

四、总结

  1. @State、@Prop:父子单向传递,需要传参,不传不报错只是不起作用。
  2. @State、@Link:父子双向同步,必须传参否则报错。
  3. @Provide、@Consume:数据提供者和消费者的关系,可以跨多层组件使用,双向同步,直接使用不用传参。
相关推荐
贾伟康10 小时前
【共创稿事节】HarmonyOS 7.0 BindContentCover全屏模态:从接入到生产验证
性能优化·实战·harmonyos·arkts·arkui
KevinChaos13 小时前
声音明信片实验室 03|HarmonyOS 7.0 音频空间化:双版本试听无缝切换
harmonyos
贾伟康13 小时前
【共创稿事节】HarmonyOS 7.0 Menu菜单与上下文:从接入到生产验证
性能优化·实战·harmonyos·arkts·arkui
码间留白13 小时前
鸿蒙端对接 BLE 血压计:从一次握手到读数入库(二)设备篇
物联网·uni-app·鸿蒙·蓝牙ble·血压计
行者-全栈开发14 小时前
Flutter 插件 device_calendar_plus 开源鸿蒙适配实战:从权限弹窗失灵到循环日程跑通
flutter·跨平台·harmonyos·arkts·日历·适配·开源鸿蒙
贾伟康16 小时前
【共创稿事节】HarmonyOS 7.0 BindSheet半模态浮层:从接入到生产验证
性能优化·实战·harmonyos·arkts·arkui
JosieBook16 小时前
【鸿蒙PC GUI适配】chiaki-ng 移植的工程实践:Qt6/QML 与 ArkUI 的混合窗口架构
华为·架构·harmonyos
Dream-Y.ocean1 天前
鸿蒙PC平台宅匠 3D 室内设计适配实战:基于 Electron 壳方案的 Three.js 双渲染引擎与参数化户型编辑器开发
javascript·3d·harmonyos
行者-全栈开发1 天前
【共创稿事节】HarmonyOS 应用上架全流程中的隐私合规:权限最小化、数据本地化与 AppAnalyzer 体检
harmonyos·鸿蒙·隐私合规·应用上架·agc·appanalyzer
贾伟康1 天前
HarmonyOS API 26 UKey PIN 授权门禁:状态查询、失败归因与资源闭环
华为·harmonyos