@ObservedV2使用指南

一、基础概念
装饰器说明
装饰器的作用
@ObservedV2标记一个class类为可观测数据模型,类内部属性不会自动监听,需要搭配@Trace
@Trace标记类中的单个属性,属性变化时触发UI刷新
@LocalV2组件内本地状态,接收ObservedV2实例
@ParamV2父组件传给子组件的ObservedV2对象参数

>V1与V2核心区别
>-V1:@Observed`整个类所有属性都可监听
>-V2:@ObservedV2`**不会自动监听所有字段,必须手动给需要响应式更新的字段加@Trace

二、导入依赖
import{ObservedV2,Trace,LocalV2,ParamV2}from'@ohos.arkui.stateV2';
三、基础示例:简单对象监听
1.定义数据模型类(@ObservedV2+@Trace)

// 数据模型
@ObservedV2
class UserInfo {
  @Trace name: string = "张三";
  @Trace age: number = 18;
  // 没有@Trace修饰,修改不会刷新UI
  remark: string = "不会触发UI更新";
}


2.组件内使用@LocalV2创建实例

@ComponentV2
struct DemoPage {
  // 创建可观测实例
  @LocalV2 user: UserInfo = new UserInfo();

  build() {
    Column({ space: 20 }) {
      Text(`姓名:${this.user.name}`)
      Text(`年龄:${this.user.age}`)

      Button("修改姓名")
        .onClick(() => {
          // @Trace属性变化 → UI刷新
          this.user.name = "李四";
        })

      Button("修改无Trace字段")
        .onClick(() => {
          // remark无@Trace,UI不会刷新
          this.user.remark = "修改了备注";
        })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}


关键点:@ComponentV2是V2状态组件装饰器,必须配套使用,不能和老版本@Component混用V2装饰器。
四、嵌套对象监听
嵌套对象,子对象类也需要加上@ObservedV2,子属性加@Trace。

// 子模型
@ObservedV2
class Address {
  @Trace city: string = "武汉";
  @Trace street: string = "街道1号";
}

// 父模型
@ObservedV2
class Person {
  @Trace name: string = "小明";
  // 引用子可观测对象
  @Trace address: Address = new Address();
}

@ComponentV2
struct NestedDemo {
  @LocalV2 person: Person = new Person();

  build() {
    Column({space:10}){
      Text(`城市:${this.person.address.city}`)
      Button("修改城市")
        .onClick(()=>{
          this.person.address.city = "上海"
        })
    }
  }
}


五、数组监听(@ObservedV2+@Trace)
数组引用需要加@Trace;数组内对象必须是@ObservedV2类实例,修改数组元素属性才会刷新UI

@ObservedV2
class TodoItem {
  @Trace content: string = "";
  @Trace finished: boolean = false;
  constructor(content:string){
    this.content = content;
  }
}

@ObservedV2
class TodoList {
  @Trace list: TodoItem[] = []
}

@ComponentV2
struct ArrayDemo {
  @LocalV2 todoData: TodoList = new TodoList()

  build() {
    Column(){
      ForEach(this.todoData.list,(item:TodoItem)=>{
        Text(`${item.content} 完成:${item.finished}`)
      },(item)=>item.content)

      Button("添加一条待办")
        .onClick(()=>{
          this.todoData.list.push(new TodoItem("新任务"))
        })
    }
  }
}


六、父子组件传ObservedV2对象(@ParamV2)
父组件传递ObservedV2实例给子组件,子组件使用@ParamV2接收。

// 数据模型
@ObservedV2
class CountModel{
  @Trace count:number = 0;
}

// 子组件
@ComponentV2
struct ChildComp {
  // 接收父传过来的可观测对象
  @ParamV2 data: CountModel

  build(){
    Column(){
      Text(`子组件计数:${this.data.count}`)
      Button("子组件修改")
        .onClick(()=>{
          this.data.count++
        })
    }
  }
}

// 父组件
@ComponentV2
struct ParentPage {
  @LocalV2 counter: CountModel = new CountModel()

  build(){
    Column(){
      Text(`父组件计数:${this.counter.count}`)
      Button("父组件修改")
        .onClick(()=>{
          this.counter.count++
        })
      // 传给子组件
      ChildComp({data: this.counter})
    }
  }
}


特性:父子共用同一个对象引用,任意一方修改@Trace属性,两边UI同时刷新。
七、V2状态全家桶对照表
表格
装饰器    使用位置    作用
@ObservedV2类    标记类为响应式可观测模型
@Trace    类属性    属性变更触发ui更新,必须显式添加
@ComponentV2    struct组件    开启V2状态管理能力
@LocalV2    struct内变量    组件本地可观测状态,内部创建ObservedV2实例
@ParamV2    struct内变量    接收父组件传入的ObservedV2实例对象
@OnceV2    struct内变量    仅第一次赋值生效的参数

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐