@Prop

作用:@Prop从父组件接收数据

共享方向:父到子

@Entry
@Component
struct Test{
  @State num:number=0
  build(){
    Column(){
      //第一个num为子组件中的变量名,第二个num为父组件中的变量名
      PropComponent({num:this.num})
      Button("+1")
        .onClick(()=>{
          this.num++
        })
    }
    .width("100%")
  }
}
​
@Component
struct PropComponent{
  //这里的变量名必须与父组件传值中冒号前的变量名一致
  @Prop num:number
  build(){
    Text(this.num.toString())
  }
}

@Provide与@Consume

作用:@Provide作为数据的提供方,可以更新其子孙节点的数据;@Consume接收@Provide的数据

共享方向:双向

使用案例:

@Entry
@Component
struct ProvidePage {
  @Provide count: number = 1
  build() {
    Column() {
      Text(this.conunt.toString)
      //调用子组件时不用传递数据
      ConsumeComponent()
    }
  }
}
​
//子组件
@Component
struct ConsumeComponent {
  //变量名要跟@Provide一样
  @Consume count: number
  build() {
    Column() {
      Text(this.count.toString())
      //点击+1
      Text("点击+1").onClick(() => {
        this.count++
      })
    }
  }
}

@Link

作用:将数据与父组件的数据共享

共享方向:双向

使用案例:

@Entry
@Component
struct ProvidePage {
  @State count: number = 1
  build() {
    Column() {
      Text("父组件中的count:"+this.count.toString())
      //第一个count为在子组件中的变量名,第二个count为在父组件中的变量名
      LinkComponent({count:$count})
    }
    .width("100%")
  }
}
​
//子组件
@Component
struct LinkComponent {
  //变量名要跟父组件传值中冒号前的变量名一致
  @Link count: number
  build() {
    Column() {
      Text("子组件中的count:"+this.count.toString())
      //点击+1
      Text("点击+1").onClick(() => {
        this.count++
      })
    }
  }
}

@ObjectLink与@Observe

作用:类、对象、数组类型数据的数据共享

//@Observe用于类、对象、数组的声明
@Observed
class stu{
  public id:string
  name:string
​
  constructor(id:string, name:string) {
    this.id=id
    this.name=name
  }
}
​
@Entry
@Component
struct Test{
  @State me:stu=new stu("001", "张三")
  build(){
    Column(){
      Text("学号:"+this.me.id)
      Text("姓名:"+this.me.name)
      //第一个me为子组件中的变量名,第二个me为父组件中的变量名
      ObjectLinkComponent({ me: this.me })
    }
  }
}
​
@Component
struct ObjectLinkComponent{
    //变量名要与父组件传值中冒号前的变量名一致
  @ObjectLink me:stu
  build(){
    TextInput({placeholder:"请输入学号"})
      .onChange((value)=>{
        this.me.id=value
      })
  }
}

补充几点:

1、@Prop, @Link 装饰的变量名不一定必须在父子组件间用相同变量名,保持一致只是方便代码理解,类型必须要一致;

2、@Provide, @Consume 关联一是以相同变量名实现有关联,二可用别名(在装饰器后加括号添加别名字符串)进行关联;

3、@State, @Prop, @Link, @Provide, @Consume 都可同步类、对象、数组,只是观察变化只能在变量本身或一级属性或元素;有嵌套情况时需要考虑用@Observe, @ObjectLink以观察二级以上属性变化对UI进行自动刷新;

总结

  • @Prop只能用于子组件获取父组件的数据,无法同步

  • @Link可以同步父子组件的数据

  • @Provide配合@Consume可以同步父组件与子孙组件之间的数据,优点是不用传参,代码简单

  • @ObjectLink配合@Observe可以同步父子组件的类、对象、数组类型的数据

Logo

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

更多推荐