第五节 组件级状态管理

@State

@State用于装饰当前组件的状态变量的,当变量发生改变的时候会驱动当前组件的视图刷新

注意:@State装饰的变量必须要进行本地初始化

@Entry
@Component
struct Index {
  @State count: number = 1

  build() {
    // 外壳容器
    Column() {
      Row({
        space: 10
      }) {
        Text('@State')
          .textStyle()
        // 计数器组件
        Counter() {
          Text(this.count.toString())
            .textStyle()
        }
        .onInc(() => this.count++)
        .onDec(() => this.count--)
      }
    }
    .width('100%')  // 宽度撑满整个屏幕
    .height('100%')  // 高度撑满整个屏幕
    .justifyContent(FlexAlign.Center)
  }
}

@Extend(Text) function textStyle() {
  .fontSize(25)
  .fontWeight(FontWeight.Bold)
}

@Prop

@Prop用于装饰状态变量,可以由数据驱动视图的刷新

重点:可以将父组件中的状态变化同步到子组件中,而子组件的变化不会同步到父组件中(父传子)

@Entry
@Component
struct Index {
  @State count: number = 1

  build() {
    // 外壳容器
    Column() {
      Column({
        space: 10
      }) {
        // 父组件标题
        Text('父组件')
          .textStyle()

        // 父组件计数器
        Row({
          space: 10
        }) {
          Text('@State')
            .textStyle()
          Counter() {
            Text(this.count.toString())
              .textStyle()
          }
          .onInc(() => this.count++)
          .onDec(() => this.count--)
        }

        // 子组件
        Child({ count: this.count })
      }
      .backgroundColor('#EFEFEF')
    }
    .width('100%')  // 宽度撑满整个屏幕
    .height('100%')  // 高度撑满整个屏幕
    .justifyContent(FlexAlign.Center)
  }
}

@Extend(Text) function textStyle() {
  .fontSize(25)
  .fontWeight(FontWeight.Bold)
}

@Component
struct Child {
  @Prop count: number

  build() {
    Column({
      space: 10
    }) {
      // 子组件标题
      Text('子组件')
        .textStyle()

      // 子组件计数器
      Row({
        space: 10
      }) {
        Text('@Prop')
          .textStyle()
        Counter() {
          Text(this.count.toString())
            .textStyle()
        }
        .onInc(() => this.count++)
        .onDec(() => this.count--)
      }
    }
    .backgroundColor('#CCE3C8')
  }
}

@Link

@Link用于装饰状态变量,可以由数据驱动视图刷新

重点:父组件状态变量改变的时候会同步到子组件中,子组件的变化也会同步到父组件中(双向同步)

注意:@Link装饰的变量不允许本地初始化,只能由父组件通过传参的方式进行初始化,并且父组件必须使用**$变量名**的方式传参,表示传递的变量是引用

@Entry
@Component
struct Index {
  @State count: number = 1

  build() {
    // 外壳容器
    Column() {
      Column({
        space: 10
      }) {
        // 父组件标题
        Text('父组件')
          .textStyle()

        // 父组件计数器
        Row({
          space: 10
        }) {
          Text('@State')
            .textStyle()
          Counter() {
            Text(this.count.toString())
              .textStyle()
          }
          .onInc(() => this.count++)
          .onDec(() => this.count--)
        }

        // 子组件
        Child({ count: $count })
      }
      .backgroundColor('#EFEFEF')
    }
    .width('100%')  // 宽度撑满整个屏幕
    .height('100%')  // 高度撑满整个屏幕
    .justifyContent(FlexAlign.Center)
  }
}

@Extend(Text) function textStyle() {
  .fontSize(25)
  .fontWeight(FontWeight.Bold)
}

@Component
struct Child {
  @Link count: number

  build() {
    Column({
      space: 10
    }) {
      // 子组件标题
      Text('子组件')
        .textStyle()

      // 子组件计数器
      Row({
        space: 10
      }) {
        Text('@Link')
          .textStyle()
        Counter() {
          Text(this.count.toString())
            .textStyle()
        }
        .onInc(() => this.count++)
        .onDec(() => this.count--)
      }
    }
    .backgroundColor('#CCE3C8')
  }
}

@Provide和@Consume

重点:用于跨组件成绩传递状态信息,@Provide用于装饰祖先组件的状态信息,@Consume用于装饰后代组件的状态信息,祖先组件和后代组件可以实现双向的数据同步

注意:@Provide装饰的变量必须要本地初始化,而@Consume装饰的变量不允许本地初始化

@Entry
@Component
struct Index {
  @Provide('count') parentCount: number = 1

  build() {
    // 外壳容器
    Column() {
      Column({
        space: 10
      }) {
        // 祖先组件标题
        Text('祖先组件')
          .textStyle()

        // 祖先组件计数器
        Row({
          space: 10
        }) {
          Text('@Provide')
            .textStyle()
          Counter() {
            Text(this.parentCount.toString())
              .textStyle()
          }
          .onInc(() => this.parentCount++)
          .onDec(() => this.parentCount--)
        }

        // 父组件
        Parent()
      }
      .backgroundColor('#EFEFEF')
    }
    .width('100%')  // 宽度撑满整个屏幕
    .height('100%')  // 高度撑满整个屏幕
    .justifyContent(FlexAlign.Center)
  }
}

@Extend(Text) function textStyle() {
  .fontSize(25)
  .fontWeight(FontWeight.Bold)
}

@Component
struct Parent {
  build() {
    Column({
      space: 10
    }) {
      // 父组件标题
      Text('父组件')
        .textStyle()
      // 子组件
      Child()
    }
    .backgroundColor('#ff0000')
  }
}

@Component
struct Child {
  @Consume('count') childCount: number

  build() {
    Column({
      space: 10
    }) {
      // 子组件标题
      Text('子组件')
        .textStyle()

      // 子组件计数器
      Row({
        space: 10
      }) {
        Text('@Consume')
          .textStyle()
        Counter() {
          Text(this.childCount.toString())
            .textStyle()
        }
        .onInc(() => this.childCount++)
        .onDec(() => this.childCount--)
      }
    }
    .backgroundColor('#CCE3C8')
  }
}
Logo

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

更多推荐