【鸿蒙系统学习笔记】状态管理

一、介绍

资料来自官网:文档中心

在声明式UI编程框架中,UI是程序状态的运行结果,用户构建了一个UI模型,其中应用的运行时的状态是参数。当参数改变时,UI作为返回结果,也将进行对应的改变。这些运行时的状态变化所带来的UI的重新渲染,在ArkUI中统称为状态管理机制。

【鸿蒙系统学习笔记】状态管理_第1张图片

  • View(UI):UI渲染,指将build方法内的UI描述和@Builder装饰的方法内的UI描述映射到界面。
  • State:状态,指驱动UI更新的数据。用户通过触发组件的事件方法,改变状态数据。状态数据的改变,引起UI的重新渲染。

 【鸿蒙系统学习笔记】状态管理_第2张图片

说明:

@State装饰器标记的变量必须初始化,不能为空值

@State支持Object、class、string、number、boolean、enum类型以及这些类型的数组

嵌套类型以及数组中的对象属性无法触发视图更新 

二、父子组件数据同步

2.1、@Prop装饰器:父子单向同步

@Prop装饰的变量可以和父组件建立单向的同步关系。@Prop装饰的变量是可变的,但是变化不会同步回其父组件。

【鸿蒙系统学习笔记】状态管理_第3张图片

@Entry
@Component
struct StatePage {
  @State name: string = '汤姆'

  build() {
    Row() {
      Column({space:8}) {
        Text(this.name)
          .StatePage_textSty()
        // 父组件的数据源的修改会同步给子组件
          Button('点我')
            .StatePage_btnSty(() =>  this.name = this.name === '汤姆' ? '杰克' : '汤姆')
        Divider()
        PropPage({contentProp:this.name})
      }
      .width('100%')
    }
    .height('100%')
  }
}

//存放一个@Prop装饰的状态数据,方便父子组件数据传递  State ---> Prop
@Component
struct PropPage {
  @Prop contentProp:string
  build() {
    Column({space:8}){
      Text('prop--' + this.contentProp)
        .StatePage_textSty()
      // @Prop装饰的变量不会同步给父组件
      Button('修改prop的值')
        .StatePage_btnSty(() => this.contentProp = '杰克逊')
    }
  }
}

//text和button重复的样式进行复用
@Extend(Text) function StatePage_textSty(){
  .fontSize(30)
  .fontWeight(FontWeight.Bold)
  .fontColor(Color.Green)
}

@Extend(Button) function StatePage_btnSty(click:Function){
  .fontSize(30)
  .onClick(() => click())
}

上面示例中:

父组件StatePage,子组件PropPage

①当点击父组件的按钮时,父组件的name发生变化,子组件的contentProp 也发生了变化

②当点击子组件的按钮时,子组件的contentProp 发生变化,但父组件的name未改变

✍使用@Prop,父子单向同步

2.2、@Link装饰器:父子双向同步 

@Link装饰的变量与其父组件中的数据源共享相同的值。

限制条件:@Link装饰器不能在@Entry装饰的自定义组件中使用

【鸿蒙系统学习笔记】状态管理_第4张图片

【鸿蒙系统学习笔记】状态管理_第5张图片

上面示例中:

父组件StatePage,子组件LinkPage

①当点击父组件的按钮时,父组件的name发生变化,子组件的contentLink也发生了变化

②当点击子组件的按钮时,子组件的contentLink发生变化,父组件的name也发生了变化

✍使用@Link,父子双向同步

三、后代组件双向同步

3.1、@Provide装饰器和@Consume装饰器:与后代组件双向同步

@Provide和@Consume,应用于与后代组件的双向数据同步,应用于状态数据在多个层级之间传递的场景。

【鸿蒙系统学习笔记】状态管理_第6张图片

下面代码具有相同的变量名,使用@Provide和@Consume实现与后代组件数据同步

@Entry
@Component
struct ProvideConsume {
  @Provide name: string = '关羽'

  build() {
    Row() {
      Column({space:20}) {
        Text(this.name)
          .ProvideConsume_textStyle()
          .onClick(() => this.name = '张飞')
        Divider()
        ProvideConsume_son()
      }
      .width('100%')
    }
    .height('100%')
  }
}

@Component
struct ProvideConsume_son {
  build() {
    Column({space:20}){
      Text('子组件:')
        .ProvideConsume_textStyle()
      Divider()
      ProvideConsume_sun()
    }
  }
}

@Component
struct ProvideConsume_sun{
  @Consume name:string
  build() {
    Column(){
      Text('孙组件:'+ this.name)
        .ProvideConsume_textStyle()
        .onClick(() => {this.name = '刘备'})
    }
  }
}

@Extend(Text) function ProvideConsume_textStyle(){
  .fontSize(30)
  .fontWeight(FontWeight.Bold)
  .fontColor(Color.Green)
}

下面代码变量名不一致,但具备相同的别名,使用@Provide和@Consume实现与后代组件数据同步

【鸿蒙系统学习笔记】状态管理_第7张图片 

上面示例中:

父组件ProvideConsume,子组件ProvideConsume_son,孙组件ProvideConsume_sun

①点击父组件的按钮,父组件的name发生变化,孙组件的name也发生变化

②点击孙组件的按钮,孙组件与父组件的name同时发生变化


✍父组件使用@Provide将name变量给孙组件,孙组件通过使用@Consume去获取@Provide提供的变量,建立在@Provide和@Consume之间的双向数据同步

✍@Provide和@Consume可以通过相同的变量名或者相同的变量别名绑定,变量类型必须相同。

 

你可能感兴趣的:(学习,笔记)