ArkTS之状态管理二

28 阅读2分钟

在上一篇的基础上中我们大致了解了@State,@Prop, @Link, @Provide/@Consume的基本使用方法,在这一篇中我们会进一步的了解到@Observed和@ObjectLink.

在我们上篇的内容中几乎都是简单的变量前面加一个修饰器进行演示操作,那么如果我们将内容变得复杂起来了呢?就比如说我们定义一个对象或者定义了一个类,然后再定义一个数组里面有多个对象,那么这样嵌套起来,我们上一篇中讲到的修饰器就无法进行监听改变了,因为它们只能观察到第一层的变化也就是说我们嵌套进入第二层或者多层的时候就无法再进行改变了。这篇内容的"主角"因此而诞生 ---@Observed和@ObjectLink

我们先来介绍一下使用这两个装饰器的前置条件

@Observed类装饰器:

它是用来装饰Class的,也就是说它需要放在class定义前,使用new创建类对象

@ObservedLink类装饰器:

它只能修饰被@Observed修饰的class类型

它不能出现在被@Entry修饰起来的组件中

演示如下

[Observed1.mp4] live.csdn.net/v/468512

@Entry  
@Component  
**struct** ObservedPage {  
  @State form: formationModel[] = [  
    **new** formationModel("老明", 40),  
    **new** formationModel("小明", 18),  
  ]  
  
  build() {  
    Column() {  
      ForEach(**this**.form, (item: formationModel) => {  
        observedLink({ child: item })  
      })  
    }  
  }  
}  
  
@Component  
**struct** observedLink {  
  @ObjectLink child: formationModel  
  build() {  
    Column({ space: 12 }) {  
      Text(**this**.child.Name).fontSize(30)  
      Text(**this**.child.num.toString())  
      Button("Num++")  
        .onClick(() => { **this**.child.num++ })  
      Button("Num--")  
        .onClick(() => { **this**.child.num-- })  
    }  
  }  
}  
  
@Observed  
**class** formationModel {  
  Name: string = ""  
  num: number = 0  
  **constructor**(name: string, num: number) {  
    **this**.Name = name  
    **this**.num = num  
  }  
}

如代码所示@ObservedLink装饰的变量和数据源的关系是双向同步的,但是不能给@ObservedLink所装饰的变量赋予初值,否则直接报错。

假如我们不新new一个对象那么是否真的不会发生改变呢?

[Observed2.mp4] live.csdn.net/v/468516

@Entry  
@Component  
**struct** ObservedPage {  
  // @State form: formationModel[] = [  
  //   new formationModel("老明", 40),  
  //   new formationModel("小明", 18),  
  // ]  
  @State form: formationModel[] = [  
    {Name: "老明", num: 40},  
    {Name: "小明", num: 18}  
  ]  
  
  build() {  
    Column() {  
      ForEach(**this**.form, (item: formationModel) => {  
        observedLink({ child: item })  
      })  
    }  
  }  
}  
  
@Component  
**struct** observedLink {  
  @ObjectLink child: formationModel  
  build() {  
    Column({ space: 12 }) {  
      Text(**this**.child.Name).fontSize(30)  
      Text(**this**.child.num.toString())  
      Button("Num++")  
        .onClick(() => { **this**.child.num++ })  
      Button("Num--")  
        .onClick(() => { **this**.child.num-- })  
    }  
  }  
}  
  
@Observed  
**class** formationModel {  
  Name: string = ""  
  num: number = 0  
  // constructor(name: string, num: number) {  
  //   this.Name = name  
  //   this.num = num  
  // }  
}

image.png 如上演示与代码,确实。如果我们不实例化一个类并且将它new出来他只会渲染我们的第一次不会再进行第二次渲染,那么变量是否改变了呢?我们通过打印日志便可以得知

变量再改变但是画面不变,因为数据源并没有将@Observed修饰的类new出来所以无法监听其中值的改变

  Harmony OS NEXT      API12 本次就暂时介绍这么多 谢谢各位的观看,有错误不足的地方, 本人乐于接受各位的意见