• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 数据对象状态变量的迁移指导
2<!--Kit: ArkUI-->
3<!--Subsystem: ArkUI-->
4<!--Owner: @jiyujia926-->
5<!--Designer: @s10021109-->
6<!--Tester: @TerryTsao-->
7<!--Adviser: @HelloCrease-->
8
9本文档主要介绍数据对象内的状态变量的迁移场景,包含以下场景。
10| V1装饰器名                | V2装饰器名                  |
11|------------------------|--------------------------|
12|[\@ObjectLink](./arkts-observed-and-objectlink.md)/[\@Observed](./arkts-observed-and-objectlink.md) /[\@Track](./arkts-track.md)|[\@ObservedV2](./arkts-new-observedV2-and-trace.md)/[\@Trace](./arkts-new-observedV2-and-trace.md)|
13
14## 各装饰器迁移示例
15
16### \@ObjectLink/\@Observed/\@Track -> \@ObservedV2/\@Trace
17**迁移规则**
18
19在V1中,\@Observed与\@ObjectLink装饰器用于观察类对象及其嵌套属性的变化,但V1只能观察对象的第一层属性。嵌套对象的属性需要通过自定义组件和\@ObjectLink观察。此外,V1中提供了\@Track装饰器实现对属性级别变化的精确控制。
20
21在V2中,结合使用\@ObservedV2和\@Trace,可以高效实现类对象及其嵌套属性的深度观察,省去对自定义组件的依赖,简化开发流程。同时,\@Trace装饰器具备精确更新能力,替代V1中的\@Track,实现更高效的UI刷新控制。根据不同场景,有以下迁移策略:
22
23- 嵌套对象的属性观察:V1中需要通过自定义组件和\@ObjectLink观察嵌套属性,V2中则可以使用\@ObservedV2和\@Trace直接观察嵌套对象,简化了代码结构。
24- 类属性的精确更新:V1中的\@Track可以用V2中的\@Trace取代,\@Trace可以同时观察和精确更新属性变化,使代码更简洁高效。
25
26**示例**
27
28**嵌套对象属性观察方法**
29
30在V1中,无法直接观察嵌套对象的属性变化,只能观察到第一层属性的变化。必须通过创建自定义组件并使用\@ObjectLink来实现对嵌套属性的观察。V2中使用\@ObservedV2和\@Trace,可以直接对嵌套对象的属性进行深度观察,减少复杂度。
31
32V1实现:
33
34```ts
35@Observed
36class Address {
37  city: string;
38
39  constructor(city: string) {
40    this.city = city;
41  }
42}
43
44@Observed
45class User {
46  name: string;
47  address: Address;
48
49  constructor(name: string, address: Address) {
50    this.name = name;
51    this.address = address;
52  }
53}
54
55@Component
56struct AddressView {
57  // 子组件中@ObjectLink装饰的address从父组件初始化,接收被@Observed装饰的Address实例
58  @ObjectLink address: Address;
59
60  build() {
61    Column() {
62      Text(`City: ${this.address.city}`)
63      Button("city +a")
64        .onClick(() => {
65          this.address.city += "a";
66        })
67    }
68  }
69}
70
71@Entry
72@Component
73struct UserProfile {
74  @State user: User = new User("Alice", new Address("New York"));
75
76  build() {
77    Column() {
78      Text(`Name: ${this.user.name}`)
79      // 无法直接观察嵌套对象的属性变化,例如this.user.address.city
80      // 只能观察到对象第一层属性变化,所以需要将嵌套的对象Address抽取到自定义组件AddressView
81      AddressView({ address: this.user.address })
82    }
83  }
84}
85```
86
87V2迁移策略:使用\@ObservedV2和\@Trace。
88
89```ts
90@ObservedV2
91class Address {
92  @Trace city: string;
93
94  constructor(city: string) {
95    this.city = city;
96  }
97}
98
99@ObservedV2
100class User {
101  @Trace name: string;
102  @Trace address: Address;
103
104  constructor(name: string, address: Address) {
105    this.name = name;
106    this.address = address;
107  }
108}
109
110@Entry
111@ComponentV2
112struct UserProfile {
113  @Local user: User = new User("Alice", new Address("New York"));
114
115  build() {
116    Column() {
117      Text(`Name: ${this.user.name}`)
118      // 通过@ObservedV2和@Trace可以直接观察嵌套属性
119      Text(`City: ${this.user.address.city}`)
120      Button("city +a")
121        .onClick(() => {
122          this.user.address.city += "a";
123        })
124    }
125  }
126}
127```
128**类属性变化观测**
129
130在V1中,\@Observed用于观察类实例及其属性的变化,\@Track用于类对象的属性级的观察。在V2中,\@Trace实现了观察和更新属性级别变化的能力,搭配\@ObservedV2实现高效的UI更新。
131
132V1实现:
133
134```ts
135@Observed
136class User {
137  @Track name: string;
138  @Track age: number;
139
140  constructor(name: string, age: number) {
141    this.name = name;
142    this.age = age;
143  }
144}
145
146@Entry
147@Component
148struct UserProfile {
149  @State user: User = new User('Alice', 30);
150
151  build() {
152    Column() {
153      Text(`Name: ${this.user.name}`)
154      Text(`Age: ${this.user.age}`)
155      Button("increase age")
156        .onClick(() => {
157          this.user.age++;
158        })
159    }
160  }
161}
162```
163
164V2迁移策略:使用\@ObservedV2和\@Trace。
165
166```ts
167@ObservedV2
168class User {
169  @Trace name: string;
170  @Trace age: number;
171
172  constructor(name: string, age: number) {
173    this.name = name;
174    this.age = age;
175  }
176}
177
178@Entry
179@ComponentV2
180struct UserProfile {
181  @Local user: User = new User('Alice', 30);
182
183  build() {
184    Column() {
185      Text(`Name: ${this.user.name}`)
186      Text(`Age: ${this.user.age}`)
187      Button("Increase age")
188        .onClick(() => {
189          this.user.age++;
190        })
191    }
192  }
193}
194```
195