Skip to main content

05状态管理

V2版本状态管理


@ComponentV2

@Component装饰器一样,@ComponentV2装饰器用于装饰自定义组件:

  • @ComponentV2装饰的自定义组件中,开发者仅可以使用全新的状态变量装饰器,包括@Local@Param@Once@Event@Provider@Consumer等。

@Local装饰器:组件内部状态

类似于V1中的@State

  • @Local表示组件内部的状态,使得自定义组件内部的变量具有观测变化的能力:

  • @Local装饰的变量无法从外部初始化,因此必须在组件内部进行初始化。

  • 当被@Local装饰的变量变化时,会刷新使用该变量的组件。

  • @Local支持观测numberbooleanstringObjectclass等基本类型以及ArraySetMapDate等内嵌类型。

* @Local的观测能力仅限于被装饰的变量本身。

当装饰简单类型时,能够观测到对变量的赋值;

当装饰对象类型时,仅能观测到对对象整体的赋值;

当装饰数组类型时,能观测到数组整体以及数组元素项的变化;

当装饰Array、Set、Map、Date等内嵌类型时,可以观测到通过API调用带来的变化。详见观察变化。

  • @Local支持null、undefined以及联合类型。

案例:修改基础类型和对象类型(更新属性值/引用) Local效果

class Student{
age:number
username:string

constructor(age: number, username: string) {
this.age = age;
this.username = username;
}

}

@Entry
@ComponentV2
struct LocalPage {
// 基础类型 当装饰简单类型时,能够观测到对变量的赋值;
@Local message: string = 'Hello World';
// 对象类型 当装饰对象类型时,仅能观测到对对象整体的赋值
@Local student:Student = new Student(18,"帝心")

build() {
Column({ space: 30 }) {
// 基础类型 能够观察到 变量赋值
Row(){
Text(this.message)
Button('change message')
.onClick(() => {
this.message = "hello Local"
})
}
// 对象类型 修改属性 观察不到 属性值 修改
Row(){
Text(this.student.username)
Button('change username')
.onClick(() => {
this.student.username = "猪老师"
})
}
// 对象类型 整个对象引用改变 能观察到 对象整体赋值
Row(){
Text(this.student.username)
Button('change username')
.onClick(() => {
this.student = new Student(20,"猪老师")
})
}
}
.width('100%')
.height('100%')

}
}

@ObservedV2装饰器和@Trace装饰器:类属性变化观测

注意:被@ObservedV2@Trace装饰的类+属性,new出来的对象即可观测属性变化,即数据驱动UI更新。无需@Local重复装饰。

  • @ObservedV2装饰器与@Trace装饰器用于装饰类以及类中的属性,使得被装饰的类和属性具有深度观测的能力:

  • @ObservedV2装饰器与@Trace装饰器需要配合使用,单独使用@ObservedV2装饰器或@Trace装饰器没有任何作用。

  • 在嵌套类中,嵌套类中的属性property被@Trace装饰且嵌套类被@ObservedV2装饰时,才具有触发UI刷新的能力。

  • 在继承类中,父类或子类中的属性property被@Trace装饰且该property所在类被@ObservedV2装饰时,才具有触发UI刷新的能力。

  • 未被@Trace装饰的属性用在UI中无法感知到变化,也无法触发UI刷新。

  • @ObservedV2的类实例目前不支持使用JSON.stringify进行序列化。

  • 使用@ObservedV2@Trace装饰器的类,需通过new操作符实例化后,才具备被观测变化的能力。


案例:修改@ObservedV2类中被@Trace装饰的属性和@Trace装饰的属性

@ObservedV2
class Student {
@Trace age: number
username: string

constructor(age: number, username: string) {
this.age = age;
this.username = username;
}
}

@Entry
@ComponentV2
struct ObservedV2_Trace {
student: Student = new Student(18, "帝心")

build() {
Column({ space: 10 }) {
// 修改 有 @Trace 装饰的属性
Text('age : ' + this.student.age)
Button('change age')
.onClick(() => {
this.student.age++ // UI更新
})
Divider().color(Color.Red)
// 修改 无 @Trace 装饰的属性
Text('username' + this.student.username)
Button('change username')
.onClick(() => {
this.student.username = "猪老师" // UI无更新
})
}
.width('100%')
.height('100%')

}
}