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 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```