1# arkui子系统状态管理ChangeLog
2
3
4# ArkUI子系统@Prop装饰器支持Object行为变化
5
6## cl.@Prop支持Object api9浅拷贝,api10变更为深拷贝
7
8**变更影响**
9@Prop支持Object在api9为浅拷贝,具体行为表现为:
10- Object类型:浅拷贝Object.keys(propObj) 返回的所有属性。即只拷贝最外层的Object,Object中property还是指向原来的父组件的数据源。
11- 数组类型:浅拷贝所有的数组项,即只拷贝最外层的array,其他行为和Object一致。
12- 拷贝Object和数组的prototype。
13
14@Prop支持Object在api10变更为深拷贝,具体行为表现为:
15- Object类型:完全拷贝Object.keys(propObj) 返回的所有属性。
16- 数组类型:完全拷贝所有的数组项;
17- 拷贝Object和数组的prototype。
18
19**适配指导**
20@Prop深浅拷贝的变更在UI渲染上的影响主要在@ObjectLink相关的场景,因为@ObjectLink会代理其修饰对象属性。
21例子如下:
22api9:PropClassAArray组件中@Prop objArray改变ClassA的属性,或者设置新的数组项,都会引起父组件StateClassAArray创建的ObjectLinkClassA中的@ObjectLink obj的改变。
23这个更新是因为父组件StateClassAArray中@State stateClassAArray到子组件PropClassAArray中@Prop objArray是浅拷贝引起的,因为浅拷贝只拷贝了数组项的引用,所以数据源也被改变,而@ObjectLink代理了数据源的属性,所以引发了ObjectLinkClassA组件中的@ObjectLink obj的更新(从StateClassAArray组件中构造的)。
24
25api10:在上述场景中,因为父组件StateClassAArray中@State stateClassAArray到子组件PropClassAArray中@Prop objArray是深拷贝,完整拷贝了ClassA的对象,所以不会改变数据源,从而不会引发ObjectLinkClassA组件中的@ObjectLink obj的更新(从StateClassAArray组件中构造的)。
26
27
28![zh-cn_image_0000001588291546](figures/zh-cn_image_0000001588291546.png)
29
30
31
32```ts
33let nextId = 0;
34
35@Observed
36class ClassA  {
37  id : number;
38  a : number;
39  constructor(a : number = 0) {
40    this.id = nextId++;
41    this.a = a;
42  }
43}
44
45@Component
46struct ObjectLinkClassA {
47  @ObjectLink obj : ClassA;
48
49  build() {
50    Row() {
51      Text(`ObjectLink: obj: ${this.obj.a}`)
52        .height(100)
53        .onClick(() => {
54          this.obj.a += 1;
55          console.info(`ObjectLink onClick ClassA property changed to  ${this.obj.a}`)
56        })
57    }.border({width: 3, color: Color.Red})
58  }
59}
60
61@Component
62struct PropClassAArray {
63  @Prop objArray : Array<ClassA> = [];
64
65  build() {
66    Column() {
67      Text(`green box: @Prop : Array<ObjectClassA> item [0] + [1]`)
68      Row() {
69        ObjectLinkClassA({ obj:  this.objArray[0] })
70        Text("[0] Assign new ClassA")
71          .height(100)
72          .onClick(() => {
73            this.objArray[0] = new ClassA();
74            console.info(`PropClassAArray[0] onClick ClassA object assign ${this.objArray[0].a}`)
75          })
76        Text("Change ClassA property")
77          .height(100)
78          .onClick(() => {
79            this.objArray[0].a += 1;
80            console.info(`PropClassAArray[1] onClick ClassA property change  ${this.objArray[1].a}`)
81          })
82      }
83    }.border({width: 3, color: Color.Green})
84  }
85}
86
87@Entry
88@Component
89struct StateClassAArray {
90  @State stateClassAArray : Array<ClassA> = [ new ClassA(), new ClassA() ];
91
92  build() {
93    Column() {
94      Column() {
95        Text("Red box: @ObjectLink from @State array item[0]")
96        Row() {
97          ObjectLinkClassA({obj : this.stateClassAArray[0] })
98          Text("Assign new ClassA")
99            .height(100)
100            .onClick(() => {
101              this.stateClassAArray[0] = new ClassA();
102              console.info(`StateClassAArray[0] onClick ClassA object assign ${this.stateClassAArray[0].a}`)
103            })
104          Text("Change ClassA property")
105            .height(100)
106            .onClick(() => {
107              this.stateClassAArray[0].a += 1;
108              console.info(`StateClassAArray onClick stateClassAArray[0] changed to  ${this.stateClassAArray[0].a}`)
109            })
110        }
111
112      }.border({width: 3, color: Color.Blue})
113
114      Divider().height(5)
115
116      // api9浅拷贝:只拷贝指向源数组项的引用,不拷贝数组项ClassA实例自身
117      // api10深拷贝:完整拷贝this.stateClassAArray,包括其数组项。
118      PropClassAArray({ objArray: this.stateClassAArray })
119    }
120  }
121}
122```