05状态管理
V2版本状态管理
@ComponentV2
和@Component装饰器一样,@ComponentV2装饰器用于装饰自定义组件:
- 在
@ComponentV2装饰的自定义组件中,开发者仅可以使用全新的状态变量装饰器,包括@Local、@Param、@Once、@Event、@Provider、@Consumer等。
@Local装饰器:组件内部状态
类似于V1中的
@State
-
@Local表示组件内部的状态,使得自定义组件内部的变量具有观测变化的能力: -
被
@Local装饰的变量无法从外部初始化,因此必须在组件内部进行初始化。 -
当被
@Local装饰的变量变化时,会刷新使用该变量的组件。 -
@Local支持观测number、boolean、string、Object、class等基本类型以及Array、Set、Map、Date等内嵌类型。
* @Local的观测能力仅限于被装饰的变量本身。
当装饰简单类型时,能够观测到对变量的赋值;
当装饰对象类型时,仅能观测到对对象整体的赋值;
当装饰数组类型时,能观测到数组整体以及数组元素项的变化;
当装饰Array、Set、Map、Date等内嵌类型时,可以观测到通过API调用带来的变化。详见观察变化。
- @Local支持null、undefined以及联合类型。
案例:修改基础类型和对象类型(更新属性值/引用)

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%')
}
}