核心目标:解决“隔代传值”问题

想象家族聚会:

  • 爷爷口袋里有家族金库(@Provider 金库)
  • 重孙子想用钱,但爸爸孙子根本不关心钱的事
  • 传统做法:爷爷 → 爸爸 → 孙子 → 重孙子 (层层传递,非常麻烦)
  • Provider/Consumer:重孙子直接喊“我要用金库的钱”,爷爷听到就给 (跨代直达)

三个关键角色

1.🏷️ @Observed (给钱包装上GPS)
// 步骤1:给“钱”做标记(必须是class)
@Observed
class FamilyMoney {
total: number = 1000; // 家族总资产
}

作用:让系统能追踪这个类内部数值的变化(就像给钱包装了GPS,一动就知道)


2. 📡 @Provider (爷爷掌管金库)
// 步骤2:爷爷把钱包公开声明为家族金库
@Entry
@Component
struct Grandpa {
@Provider familyMoney: FamilyMoney = new FamilyMoney(); //👉 创建金库

build() {
Column() {
Text(`家族总资产:${this.familyMoney.total}`) // 爷爷自己能看到
FatherComponent() // 爸爸组件(不需要传参数!)
}
}
}

关键点

  • @Provider 标记金库 (familyMoney)
  • 所有后代都能直接访问这个金库

3.📻 @Consumer (重孙子直接取钱)
// 步骤3:重孙子在任意角落访问金库
@Component
struct GreatGrandson {
@Consumer familyMoney: FamilyMoney // 👉 自动连接爷爷的金库

build() {
Button("我要花钱买玩具")
.onClick(() => {
// 直接修改金库的钱!
this.familyMoney.total -= 100 // ✅
})
}
}

神奇之处

  1. 自动连接@Consumer 后跟同名变量(familyMoney),自动找爷爷的金库
  2. 双向同步:重孙子减100元 → 爷爷的UI自动刷新显示900元

###完整流程图示

graph TB
A[爷爷组件<br>@Provider familyMoney] --> B(爸爸组件)
B --> C(孙子组件)
C --> D[重孙子组件<br>@Consumer familyMoney]
D -- 修改total值 --> A
A -- 状态更新 --> D

对比传统写法 (感受优势)

####❌ 旧方法:层层传递 (爷爷→爸爸→孙子→重孙子)

// 每层都要声明传递!
@Component
struct Father {
@Link money: FamilyMoney // 爸爸层声明

build() {
SonComponent({ money: this.money }) // 传给儿子
}
}

@Component
struct Son {
@Link money: FamilyMoney // 儿子层声明
build() {
GreatGrandson({ money: this.money }) // 传给重孙
}
}
✅ 新方法:Provider/Consumer (直达)
// 爷爷组件
@Provider familyMoney: FamilyMoney // 只在这里声明

// 重孙子组件
@Consumer familyMoney: FamilyMoney // 直接使用!

优势:中间组件完全不需要处理传递逻辑!


###💡 什么时候用?

场景 解决方案
修改亲爹的数据 @Link
修改爷爷/太爷爷的数据 @Provider+@Consumer
组件自己内部的数据 @State

总结一句话

@Provider(爷爷存钱) + @Consumer(重孙子花钱) = 跨代直接操作同一钱包,数据自动双向同步

Provider/Consumer概念版本

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐