状态管理@Prop

     

目录

1、父组件@State到子组件@Prop简单数据类型同步

2、父组件@State数组项到子组件@Prop简单数据类型同步

3、从父组件中的@State类对象属性到@Prop简单类型的同步


         @Prop主要用用于父组件到子组件的数据级联更新,父组件的数据变化会影响到子组件的数据变化,但发过来子组件的数据变化则不会影响到父组件的更新。 被@Prop装饰的变量可以和父组件建立单向的同步关系。子组件中@Prop装饰的变量是可变的,但是变化不会同步回其父组件。

        @Prop变量值初始化和更新机制:

  • 初始渲染
  1. 执行父组件的build()函数将创建子组件的新实例,将数据源传递给子组件;
  2. 初始化子组件@Prop装饰的变量。
  • 更新
  1. 子组件@Prop更新时,更新仅停留在当前子组件,不会同步回父组件;
  2. 当父组件的数据源更新时,子组件的@Prop装饰的变量将被来自父组件的数据源重置,所有@Prop装饰的本地的修改将被父组件的更新覆盖。

1、父组件@State到子组件@Prop简单数据类型同步

@Entry
@Component
struct PropDemoPage {
  @State message: string = '演示@Prop装饰器的使用:\n该装饰器用于实现修改父组件' +
    '然后子组件自动更新的单向联动(子组件数据更新不会反馈到父组件中)'
  @State index: number = 0

  build() {
    Row() {
      Column() {
        Text(this.message).letterSpacing(2)
        Text(`${this.index}`)
          .fontSize(48)
          .fontColor(Color.Pink)
          .padding(5)
          .backgroundColor("#67c8ff")
          .onClick(() => {
            this.index++
          })
        Divider()
        ChildView({ indexProp: this.index })
      }
      .width('100%')
    }
    .height('100%')
  }
}

@Component
struct ChildView {
  @Prop
  indexProp: number

  build() {
    Row() {
      Text(`${this.indexProp}`)
        .fontSize(24)
        .fontColor(Color.Pink)
        .padding(8)
        .backgroundColor("#8067c8ff")
        .onClick(() => {
          this.indexProp++
        })
    }
  }
}

        父组件中用@State修饰了变量index,通过“从父组件初始化”将其值赋值给子组件@Prop修饰的变量indexProp,同时在父组件和子组件中绑定了点击事件,表现如下:

  • 点击父组件,index的变化能够更新到子组件indexProp上。
  • 点击子组件,indexProp的变化不能更新到父组件index上。

2、父组件@State数组项到子组件@Prop简单数据类型同步

@Entry
@Component
struct PropDemo2Page {
  @State arr: number[] = [1, 2, 3];

  build() {
    Row() {
      Column() {
        Child({ value: this.arr[0] })
        Child({ value: this.arr[1] })
        Child({ value: this.arr[2] })

        Divider().height(5)

        ForEach(this.arr,
          item => {
            Child({ value: item })
          },
          item => JSON.stringify(item)
        )
        Text('replace entire arr')
          .fontSize(50)
          .onClick(() => {
            // 两个数组都包含项“3”。
            this.arr = this.arr[0] == 1 ? [3, 4, 5] : [1, 2, 3];
          })
      }
    }
  }
}

@Component
struct Child {
  @Prop value: number;

  build() {
    Text(`${this.value}`)
      .fontSize(50)
      .onClick(() => {
        this.value++
      })
  }
}

        3个子组件都有从父组件的@State变量的拷贝,所以点击子组件,会发现上面的数字会变化,但是下面的数据不会变化(因为下面的数据位于父组件中)。

状态管理@Prop_第1张图片

        把上面三个数据都改为8 8 8,在点击下面的replace entire arr,会发现数据都变成了3 4 5;为什么呢?

         当点击replace entire arr按钮的时候,由于子组件的数据变化不会反应到父组件中,虽然子组件显示8 8 8 ,但是父组件中的数据依然还是1 2 3,当点击事件发生的时候,依据判断条件就会把3 4 5赋值给数组,注意这里时发生在父组件中的赋值,其行为会反映到子组件中,所以会触发子组件的更新,也就时上面三个数据变成了3 4 5。

3、从父组件中的@State类对象属性到@Prop简单类型的同步



@Entry
@Component
struct PropDemo3Page {
  @State book: Book = new Book('100 secrets of C++', 765);

  build() {
    Column() {
      ReaderComp({ title: this.book.title, readIt: this.book.readIt })
      ReaderComp({ title: this.book.title, readIt: this.book.readIt })
    }
  }
}
class Book {
  public title: string;
  public pages: number;
  public readIt: boolean = false;

  constructor(title: string, pages: number) {
    this.title = title;
    this.pages = pages;
  }
}

@Component
struct ReaderComp {
  @Prop title: string;
  @Prop readIt: boolean;

  build() {
    Row() {
      Text(this.title)
      Text(`... ${this.readIt ? 'I have read' : 'I have not read it'}`)
        .onClick(() => this.readIt = true)
    }
  }
}

        如果图书馆有一本图书和两位用户,每位用户都可以将图书标记为已读,此标记行为不会影响其它读者用户。从代码角度讲,对@Prop图书对象的本地更改不会同步给图书馆组件中的@State图书对象。

你可能感兴趣的:(鸿蒙4.0开发,前端,javascript,开发语言,harmonyos,鸿蒙4.0,ArkTS,UI)