HarmonyOS ArkTS 父子传参神器:@Prop 装饰器 全面解析

25 阅读5分钟

HarmonyOS ArkTS 父子传参神器:@Prop 装饰器 全面解析

一起来构建生态吧~

在 ArkTS/ArkUI 的组件化开发中,组件之间传递数据是最常见的操作。虽然我们有 @State 管理组件内部状态,但父组件如何把数据传到子组件?这时你需要用到:

@Prop 装饰器(属性装饰器) —— 实现父组件向子组件的单向数据同步华为开发者官网+1


一、什么是 @Prop

简单来说:

@Prop 装饰器用于标记子组件属性,让它从父组件接收数据并与父组件保持“单向同步关系”。华为开发者官网

它和普通成员变量、状态变量的区别在于:

  • 它不是组件内部状态(不会主动触发自身重新渲染)
  • 它是由父组件初始化并驱动更新
  • 它是只会从父到子的“流动”,不会向父反馈变化(除非用双向绑定机制)华为开发者官网+1

二、核心特性(开发者需要理解的本质)

1)单向同步(父 → 子)

父组件的值变化会自动同步到子组件的 @Prop 变量,但:

子组件对这个值的修改,不会反传给父组件。 这意味着它不是双向绑定。华为开发者官网

这类似于 React 的 props,它是“只读的初始值”,不能协助子组件直接改变父组件的数据。


2)变量是“可变的本地副本”

虽然你在子组件内部读取 @Prop,它会随着父组件变化同步;但如果你在子组件内部修改这个变量

 this.count += 1

这个变化只影响当前子组件实例,不会同步回父组件。c.biancheng.net


3)支持的数据类型较丰富

@Prop 支持常见基础类型:

  • string
  • number
  • boolean
  • enum
  • 数组
  • 对象

但要注意: 某些复杂类型(嵌套的对象、Map/Set等)在深层同步时可能表现不如预期,需要格外留意。c.biancheng.net


4)不能在根组件里使用

@Prop 只适用于子组件内部,不能在由 @Entry 标记的根(入口)组件里使用,因为根组件没有父组件可以传参给它。华为开发者官网


三、基本使用方式

实际的父子传参过程一般是这样:

  1. 父组件用命名参数把数据传递给子组件
  2. 子组件@Prop 来接收这个数据
  3. 父组件数据变更时,框架自动同步更新子组件中的 @Prop

四、实战示例

我们做一个非常直观的计数器例子:


子组件:Child.ets

这是一个接收父组件数据的组件:

 @Component
 struct ChildComponent {
   @Prop count: number // 用 @Prop 接收父组件传来的值
 ​
   build() {
     Column({ space: 12 }) {
       Text(`子组件看到 count=${this.count}`)
         .fontSize(18)
         .fontColor('#333')
 ​
       Button("子组件尝试减一")
         .onClick(() => {
           this.count -= 1 // 只会影响当前子组件显示,不会回传给父组件
         })
     }
     .padding(16)
   }
 }

父组件:Parent.ets

父组件内部有一个状态变量,它通过 props 传给子组件:

 @Entry
 @Component
 struct ParentComponent {
   @State count: number = 5
 ​
   build() {
     Column({ space: 12 }) {
       Text(`父组件 count=${this.count}`)
         .fontSize(20)
         .fontColor('#111')
 ​
       Button("父组件 +1", () => {
         this.count += 1 // 父组件状态更新后,子组件也会同步刷新
       })
 ​
       // 把父组件的 count 传给子组件
       ChildComponent({ count: this.count })
     }
     .padding(16)
   }
 }

运行效果预期

✔ 初始: 父组件 count=5 子组件 count=5

✔ 点击“父组件 +1”: 父组件变成 6 子组件自动同步变成 6

✔ 在子组件里点“子组件尝试减一”: 子组件 count 变为 5,但不会影响父组件的 count 值

✔ 再次点击父组件按钮: 父组件变为 7 然后子组件再次同步变为 7

这就体现了:

父 → 子 单向同步;子组件内部的修改不会同步回父组件。 华为开发者官网+1


五、工作原理解析(像人写的理解)

为什么父组件数据变了子组件能自动刷新?背后的原因其实是:

🔹 框架会把 @Prop 标记的属性和对应的父组件数据建立起依赖关系

🔹 当父组件的状态值发生变化时,ArkTS 会重新计算子组件的 UI

🔹 子组件内部改的 @Prop 值不会触发父组件重新渲染,因为这是“副本值变化”而不是“源状态变化”

这也符合声明式 UI 的核心理念: 视图是数据的直接映射(render = f(data)) ,不需要手动操作 DOM/视图刷新。


六、@Prop 的细节和注意点

1)变量要指定类型

在声明 @Prop 时,一定要明确指定变量的类型(string/number等),否则类型推导可能失败,框架无法正确处理。华为开发者官网


2)不要在子组件里期望“改变父组件值”

因为这是单向的同步机制,改变子组件的 @Prop 不会触发父组件刷新。 如果你希望双向同步,可以参考 @Link 装饰器。CSDN


3)数组/对象等数据赋值建议用新的引用

例如:

 // 父组件更新数据
 this.items = [...this.items, newItem]

这种写法更容易触发框架的重新渲染机制,避免“引用不变造成 UI 不更新”的问题。


4)尽量避免深层传递链过长

虽然你可以把数据从父传到孙子/重孙组件,但建议层级不超过三层,否则维护成本会高,而且数据来源不清晰。


七、与 @State@Link 的比较

为了更清晰地理解 @Prop,常把它和另外两个常见装饰器比较一下:

装饰器是否能写入数据同步方向典型用途
@State组件内部状态管理组件自己的数据
@Prop✔(但只反映父组件)单向父 → 子父组件向子组件传值
@Link双向(父 ↔ 子)父子状态共享/双向绑定

八、真实业务场景下的使用建议

我们在业务中常常会遇到下面几种父子数据传递模式:

1)静态展示数据传递

例如用户信息卡片组件:

 <UserCard name={this.user.name} age={this.user.age} />

只需在子组件用 @Prop 接收即可。


2)表单输入组件绑定

如果只是读取父级数据并做展示,适合用 @Prop

如果子组件要修改父组件数据(例如输入框实时更新父组件状态),建议使用 @Link


3)Icon / 视觉辅助组件

如图标颜色、字体大小等静态参数传递,也用 @Prop 最简洁。


九、结语

@Prop 装饰器是 ArkTS 组件开发里最基础、最核心的数据传递机制之一。理解它的“单向同步”本质,有助于你在大中型项目里:

明确组件的职责边界 让组件更易于组合与复用 避免无效刷新与重复逻辑 保持数据流清晰(父 → 子)