鸿蒙开发-组件传值

192 阅读3分钟

1.@state

用@state装饰的变量,数据变化会引起UI的更新,在数据传递的过程中,如果父组件修改了数据,子组件用@state接受不能及时更新

@Entry
@Component
struct TestPage {
@State a:string='经修饰变量'
  b:string='变量'
  build() {
    Column({space:40}) {

      Row({space:30}){
        Text(this.a)
        Button('改变变量值')
          .onClick(()=>{
            this.a='修饰变量改变后'
            console.log('a---',this.a)
          })

      }
      Row({space:30}){
        Text(this.b)
        Button('改变变量值')
          .onClick(()=>{
            this.b='变量改变后'
            console.log('b---',this.b)
          })
      }
    }
    .height('100%')
    .width('100%')
    .padding({top:70})

  }
}

2.@prop

@prop装饰的变量可以和父组件建立单向的同步关系,父组件的变量变化会同步给子组件,但子组件的变化不会同步给父组件

@Entry
@Component
struct TestPage {
@State a:string='父组件值'
  build() {
    Column({space:40}) {
      Row({space:30}){
        Text('父组件----'+this.a)
        Button('改变父组件变量')
          .onClick(()=>{
            this.a='父组件改变的值'
          })

      }
        childTest({ aChild: this.a })
    }
    .height('100%')
    .width('100%')
    .padding({top:70})

  }
}

@Component
struct childTest {
@Prop aChild:string=''
  build() {
    Row({space:30}) {
     Text('子组件---'+this.aChild)
      Button('改变子组件变量')
        .onClick(()=>{
          this.aChild='子组件改变的值'
        })

    }
}
}

3.@Observed与@ObjectLink

可以在父子组件之间传递参数,在修改被装饰的子组件多层变量内的属性时,会影响父组件对应变量能引发界面重新渲染。在父组件修改数据时不需要使用splice,可以解决数据更新图片出现闪烁的问题。

@Observed
class Person{
  constructor(id: number, name: string, age: number) {
    this.id = id
    this.name = name
    this.age = age
  }
  id: number
  name: string
  age: number
}


@Entry
@Component
struct test {
  @State personList: Person[] = [
    new Person(1,'张三',18),
    new Person(2,'李四',19),
    new Person(3,'王五',20)
  ]

  build() {
    Column({ space: 20 }) {
      Text('父组件')
        .fontSize(30)
      List({ space: 10 }) {
        ForEach(this.personList, (item: Person, index: number) => {
          ItemCom({
            info: item,
            addAge: () => {
              item.age++
              item.name='小明'
 
            }
          })
        })
      }

    }
    .backgroundColor('#cbe69b')
    .width('100%')
    .height('100%')
    .padding(20)
  }
}

@Component
struct ItemCom {
  // @Prop info: Person
  @ObjectLink info :Person
  addAge = () => {

  }

  build() {
    ListItem() {
      Row({ space: 10 }) {
        Text('姓名:' + this.info.name)
        Text('年龄:' + this.info.age)
        Blank()
        Button('修改数据')
          .onClick(() => {
            this.addAge()
          })
      }
      .backgroundColor(Color.Pink)
      .padding(10)
      .width('100%')
    }
  }
}

4.@Link

使用@Link 可以实现父组件和子组件的双向同步


@Entry
@Component
struct test {
  @State count: number = 0
  build() {
    Column() {
      Text('父组件')
        .fontSize(30)
      Text(this.count.toString())
      Button('修改数据')
        .onClick(() => {
          this.count++
        })


      SonComponent({
        count:this.count
      })
    }
    .padding(10)
    .height('100%')
    .backgroundColor('#ccc')
    .width('100%')
    .alignItems(HorizontalAlign.Center)
    .padding({ top: 100 })
  }
}


@Component
  // 子组件
struct SonComponent {
  @Link count:number
  // 编写 UI
  build() {
    Column({ space: 20 }) {
      Text('我是子组件')
        .fontSize(20)
      Text('count----'+this.count)

      Column() {
        Button('修改count')
          .onClick(() => {
            this.count++
          })

      }

    }
    .backgroundColor('#a6c398')
    .alignItems(HorizontalAlign.Center)
    .width('80%')
    .margin({ top: 100 })
    .padding(10)
    .borderRadius(10)

  }
}

5.@Provide与@Consume

@Provide修饰的变量子代均可通过@Consume接受,并且数据可以进行双向同步


@Entry
@Component
  // 顶级组件
struct RootComponent {
  @Provide count:number=0
  build() {
    Column() {
      Row({space:30}){
        Text('顶级组件--'+this.count)
          .fontWeight(900)
        Button('修改count')
          .onClick(()=>{
            this.count++
          })
      }
      //二级
      ParentComponent()
    }
    .padding(10)
    .height('100%')
    .backgroundColor('#ccc')
    .width('100%')
    .alignItems(HorizontalAlign.Center)
    .padding({ top: 100 })
  }
}


@Component
  // 二级组件
struct ParentComponent {
  //接受顶级组件的数据
  @Consume count:number
  build() {
    Column() {
      Row({ space: 30 }){
        Text('我是二级组件--'+this.count)
          .fontWeight(900)
        Button('修改count')
          .onClick(()=>{
            this.count++
          })
      }

      //三级
      SonComponent()
    }
    .backgroundColor('#a6c398')
    .alignItems(HorizontalAlign.Center)
    .width('90%')
    .margin({ top: 50 })
    .padding(10)
    .borderRadius(10)

  }
}

@Component
  // 内层组件
struct SonComponent {
  @Consume count:number
  // 编写 UI
  build() {
    Column() {
      Row({space:30}){
        Text('我是内层组件--'+this.count)
          .fontWeight(900)
        Button('修改count')
          .onClick(()=>{
            this.count++
          })
      }


    }
    .backgroundColor('#bf94e4')
    .alignItems(HorizontalAlign.Center)
    .width('90%')
    .margin({ top: 50 })
    .padding(10)
    .borderRadius(10)

  }
}