@Prop装饰器:父子单向同步
@Link装饰器:父子双向同步
@Prop装饰的变量和父组件建立单向的同步关系:
·@Prop变量允许在本地修改,但修改后的变化不会同步回父组件。
·当数据源更改时,@Prop装饰的变量都会更新,并且会覆盖本地所有更改。因此,数值的同步是父组件到子组件(所属组件),子组件数值的变化不会同步到父组件。
@Link装饰的变量与其父组件中的数据源共享相同的值。
总结
·@Prop装饰的变量可以和父组件建立单向的同步关系。@Prop装饰的变量是可变的,但是变化不会同步回其父组件。
·@Link装饰的变量可以和父组件建立双向的同步关系。
@Prop装饰变量限制条件:
·@Prop装饰变量时会进行深拷贝,在拷贝的过程中除了基本类型、Map、Set、Date、Array外,都会丢失类型。例如PixelMap等通过NAPI提供的复杂类型,由于有部分实现在Native侧,因此无法在ArkTS侧通过深拷贝获得完整的数据。
@Link装饰变量限制条件:
·@Link装饰器不能在@Entry装饰的自定义组件中使用。
·@Link装饰的变量禁止本地初始化,否则编译期会报错。
·@Link装饰的变量的类型要和数据源类型保持一致,否则框架会抛出运行时错误。
@Prop变量装饰器必须指定类型,允许装饰的变量类型如下所示:
·Object、class、string、number、boolean、enum类型,以及这些类型的数组。
·不支持any,支持undefined和null。
·支持Date类型。
·API11及以上支持Map、Set类型。
·支持ArkUI框架定义的联合类型Length、ResourceStr、ResourceColor类型。
@Prop和数据源类型需要相同,有以下三种情况:
- @Prop装饰的变量和@State以及其他装饰器同步时双方的类型必须相同,示例请参考父组件@State到子组件@Prop简单数据类型同步。
- @Prop装饰的变量和@State以及其他装饰器装饰的数组的项同步时 ,@Prop的类型需要和@State装饰的数组的数组项相同,比如@Prop : T和@State : Array<T>,示例请参考父组件@State数组中的项到子组件@Prop简单数据类型同步。
- 当父组件状态变量为Object或者class时,@Prop装饰的变量和父组件状态变量的属性类型相同,示例请参考从父组件中的@State类对象属性到@Prop简单类型的同步。
Prop支持联合类型实例:
@Prop支持联合类型和undefined和null,在下面的示例中,animal类型为Animals | undefined,点击父组件Zoo中的Button改变animal的属性或者类型,Child中也会对应刷新。
Link支持联合类型实例:
@Link支持联合类型和undefined和null,在下面的示例中,name类型为string | undefined,点击父组件Index中的Button改变name的属性或者类型,Child中也会对应刷新。
代码实例
PropLinkPage
import { LinkComponent } from './components/LinkComponent';
import { PropComponent } from './components/PropComponent';
@Entry
@Component
struct PropLinkPage {
@State message: string = '第2节 @Prop和@Link';
@State stateCount:number=0;
build() {
Column({space:10}) {
Text(this.message)
.fontSize(20)
.fontWeight(FontWeight.Bold)
Button('增加次数').onClick(()=>{
this.stateCount++
})
Text('stateCount='+this.stateCount)
PropComponent({propCount:this.stateCount})
LinkComponent({linkCount:this.stateCount})
}
.height('100%')
.width('100%')
}
}
PropComponent
@Component
export struct PropComponent{
@Prop propCount:number=0
build() {
Column({space:10}){
Text('Prop子组件')
Button('增加次数').onClick(()=>{
this.propCount++
})
Text('propCount='+this.propCount)
}
.width('100%')
.padding(10)
.backgroundColor(Color.Orange)
}
}
LinkComponent
@Component
export struct LinkComponent{
@Link linkCount:number
build() {
Column({space:10}){
Text('Link子组件')
Button('增加次数').onClick(()=>{
this.linkCount++
})
Text('linkCount='+this.linkCount)
}
.width('100%')
.padding(10)
.backgroundColor(Color.Pink)
}
}