@Observed & @ObjectLink装饰器-嵌套类对象属性变化更新UI

2025-01-14 11:37:03
89次阅读
0个评论
最后修改时间:2025-03-19 20:34:03

** @Observed & @ObjectLink装饰器-嵌套类对象属性变化更新UI**

在实际应用开发中,应用会根据开发需要,封装自己的数据模型。对于多层嵌套的情况,比如二维数组,或者数组项class,或者class的属性是class,他们的第二层的属性变化是无法观察到的,当这些class的第二层属性变化时无法触发UI刷新,此时我们可以使用@Observed/@ObjectLink装饰器来实现class的第二层属性变化触发UI刷新。

@ObjectLink和@Observed类装饰器用于在涉及嵌套对象或数组的场景中进行双向数据同步:

  1. 被@Observed装饰的类,可以被观察到属性的变化。创建类时需要使用new的方式传递数据,不能使用值传递。

  2. 子组件中@ObjectLink装饰器装饰的状态变量用于接收@Observed装饰的类的实例,和父组件中对应的状态变量建立双向数据绑定。@ObjectLink不能用于entry标识的组件内。

  3. 单独使用@Observed是没有任何作用的,需要搭配@ObjectLink或者@Prop使用。 如下示例中,想要修改Person数组中的每个数据引起UI变化,需要引入多种状态数据,比较麻烦:

   class Person{
   id:number;
   name:string;
   age:number;

constructor(id:number,name:string,age:number) {
this.id = id
this.name=name
this.age=age
}
}

@Entry
@Component
struct ObservedTest {

@State
personList:Person[] = [
    new Person(1,'zs',10),
new Person(2,'ls',11),
new Person(3,'ww',12),]

build(){
Column(){
ForEach(this.personList,(item:Person,index:number)=>{
CompB({person:item,personList:$personList,index:index})
})
}
}
}

@Component
struct CompB {

person:Person

@Link
personList:Person[]

index:number

build() {
Column(){
Text(`当前person信息为:${this.person.id}-${this.person.name}-${this.person.age}`)
.width('100%')

      Button("修改person中的age")
        .onClick(()=>{
          const newAge = this.person.age +=1
          this.personList[this.index] = new Person(this.person.id,this.person.name,newAge)
          promptAction.showToast({message: this.person.age.toString()})
        })
    }

}
}

预览图

1.png

可以直接使用@Observed装饰器装饰Person类,@ObjectLink装饰组件中的Person对象,这样就可以做到当组件中的person对象改变时当前Person对象变化被监听,从而引起UI刷新。代码如下:

@Observed
class Person{
id:number;
name:string;
age:number;

constructor(id:number,name:string,age:number) {
this.id = id
this.name=name
this.age=age
}
}

@Entry
@Component
struct ObservedTest {

@State
personList:Person[] = [
   new Person(1,'zs',10),
new Person(2,'ls',11),
new Person(3,'ww',12),]

build(){
Column(){
ForEach(this.personList,(item:Person,index:number)=>{
CompB({person:item})
})
}
}

}

@Component
struct CompB {
@ObjectLink
person:Person

build() {
Column(){
Text(`当前person信息为:${this.person.id}-${this.person.name}-${this.person.age}`)
.width('100%')

      Button("修改person中的age")
        .onClick(()=>{
          this.person.age +=1
          promptAction.showToast({message: this.person.age.toString()})
        })
    }

}
}

预览如下:

2.png

当点击按钮改变person对象中的属性时,会引起UI刷新。

收藏00

登录 后评论。没有帐号? 注册 一个。