文
章
目
录
章
目
录
本文主要讲解关于鸿蒙ArkTS装饰器@Prop、@Link、@Provide和@Consume详解相关内容,让我们来一起学习下吧!
@Prop
概述
@Prop与@State有相同的语义,但初始化方式不同。@Prop装饰的变量必须使用其父组件提供的@State变量进行初始化,允许组件内部修改@Prop变量,但变量的更改不会通知给父组件,父组件变量的更改会同步到@prop装饰的变量,即@Prop属于单向数据绑定。
@Prop状态数据具有以下特征:
- 支持多种类型数据:支持class、number、boolean、string强类型数据的值类型和引用
- 类型,以及这些强类型构成的数组,即Array、Array、Array、Array。不支持any。
- 私有:仅支持组件内访问;
- 单个数据源:父组件中用于初始化子组件@Prop变量的必须是父组件定义的状态变量;
- 单向通信:子组件对@Prop变量的更改将不会同步修改父组件中的@State变量,父组件中@State的变量修改将会同步给子组件中的@Prop变量;
- 创建自定义组件时将按值传递方式给@Prop变量进行初始化:在创建组件的新实例时,必须初始化所有@Prop变量,不支持在组件内部进行初始化。
@Link
@Link装饰的变量可以和父组件的@State变量建立双向数据绑定:
- 1、支持多种类型:@Link支持的数据类型与@State相同,即class、number、string、boolean或这些类型的数组;
- 2、私有:仅支持组件内访问;
- 3、单个数据源:父组件中用于初始化子组件@Link变量的必须是父组件定义的状态变量;
- 4、双向通信:子组件对@Link变量的更改将同步修改父组件中的@State变量;
- 5、创建自定义组件时需要将变量的引用传递给@Link变量,在创建组件的新实例时,必须使用命名参数初始化所有@Link变量。@Link变量可以使用@State变量或@Link变量的引用进行初始化,@State变量可以通过’$’操作符创建引用。
- 6、@Link变量不能在组件内部进行初始化。
下面的示例是演示Child组件中的count变量是@Prop修饰的,Child2组件中的count变量是@Link修饰的,当点击Child组件的按钮时会发现只有Child组件count数据更新并更新了界面,当点击Child2组件的按钮时会发现所有的count数据都更新并且界面更新了,当点击父组件的按钮也会发现所有的组件中count数据发生了更新并且界面发生更新了
import router from '@ohos.router';
@Entry
@Component
struct Second {
@State message: string = 'Hello World Second'
@State num: number = 1
build() {
Row() {
Column() {
this.TextBuild()
Child({ count: this.num })
Child2({ count: $num })
Button() {
Text('Back')
.fontSize(45)
.fontColor($r('app.color.start_window_background'))
}
.type(ButtonType.Capsule)
.width('60%')
.height('10%')
.backgroundColor($r('app.color.button_next_background'))
.onClick(() => {
router.back()
})
Button() {
Text(`Num++ ${this.num}`)
.fontSize(45)
.fontColor($r('app.color.start_window_background'))
}
.type(ButtonType.Capsule)
.width('60%')
.height('10%')
.backgroundColor($r('app.color.button_next_background'))
.margin({ top: 20 })
.onClick(() => {
this.num++
})
}
.width('100%')
}
.height('100%')
}
@Builder TextBuild(){
Text(this.message)
.align(Alignment.Center)
.fontSize(40)
.fontWeight(FontWeight.Bold)
}
}
@Component
struct Child {
//父组件可以改变子组件,子组件不能改变父组件
@Prop count: number
build() {
Column() {
Text(`You have ${this.count} Nuggets left`).fontSize(18)
Button('count - costOfOneAttempt')
.margin(15)
.onClick(() => {
this.count--
})
}
}
}
@Component
struct Child2 {
//父组件与子组件双向绑定
@Link count: number
build() {
Column() {
Text(`You have ${this.count} Nuggets left`).fontSize(18)
Button('count - costOfOneAttempt')
.margin(15)
.onClick(() => {
this.count--
})
}
}
}
@Provide和@Consume
- 1、@Provide作为数据的提供方,可以更新其子孙节点的数据,并触发页面渲染。@Consume在感知到
- 2、@Provide数据的更新后,会触发当前自定义组件的重新渲染。
- 3、@Provide
- 装饰器参数是一个string类型的常量,用于给装饰的变量起别名。如果规定别名,则提供对应别名的数据更新。如果没有,则使用变量名作为别名。推荐使用@Provide(‘alias’)这种形式。
- 同步机制:@Provide的变量类似@State,可以修改对应变量进行页面重新渲染。也可以修改@Consume装饰的变量,反向修改@State变量。
- 必须设置初始值。
- 触发页面渲染的修改:基础类型(boolean,string,number)变量的改变;@Observed class类型变量及其属性的修改;添加,删除,更新数组中的元素。
- @Consume
- 不可设置默认初始值。
示例:
import router from '@ohos.router';
@Entry
@Component
struct Third {
//因为是数组所以需要用到@ObjectLink和@Observed
@State arrA: ClassA[] = [new ClassA(2), new ClassA(0)]
//此修饰符与@Consume组合可以让其与孙子节点数据双向绑定
@Provide("reviewVote") reviewVotes: number = 0;
build() {
Row() {
Column() {
ForEach(this.arrA, (item) => {
TextChild({ a: item })
}, (item) => item.id.toString())
ForEach(this.arrA, (item) => {
Child({ a: item })
}, (item) => item.id.toString())
Button() {
Text('Back')
.fontSize(45)
.fontColor($r('app.color.start_window_background'))
}
.type(ButtonType.Capsule)
.width('60%')
.height('10%')
.backgroundColor($r('app.color.button_next_background'))
.onClick(() => {
router.back()
})
Button() {
Text('Add')
.fontSize(45)
.fontColor($r('app.color.start_window_background'))
}
.type(ButtonType.Capsule)
.width('60%')
.height('5%')
.backgroundColor($r('app.color.button_next_background'))
.margin({ top: 20 })
.onClick(() => {
this.arrA[0].c++
})
Button() {
Text('AddChildChild'+this.reviewVotes)
.fontSize(25)
.fontColor($r('app.color.start_window_background'))
}
.type(ButtonType.Capsule)
.width('60%')
.height('10%')
.backgroundColor($r('app.color.button_next_background'))
.margin({ top: 20 })
.onClick(() => {
this.reviewVotes++
})
}
.width('100%')
}
.height('100%')
}
}
@Component
struct TextChild {
@ObjectLink a: ClassA
build() {
Column() {
Text(this.a.c + "TextChild")
.align(Alignment.Center)
.fontSize(40)
.fontWeight(FontWeight.Bold)
TextChildChild()
}
}
}
@Component
struct TextChildChild {
//此修饰符与爷爷组件的@Provide组合可以与爷爷组件双向绑定
@Consume("reviewVote") reviewVotes: number
build() {
Column() {
Button() {
Text('RemoveChildChild'+this.reviewVotes)
.fontSize(20)
.fontColor($r('app.color.start_window_background'))
}
.type(ButtonType.Capsule)
.width('60%')
.height('5%')
.backgroundColor($r('app.color.button_next_background'))
.margin({ top: 20 })
.onClick(() => {
this.reviewVotes--
})
Text(this.reviewVotes + "TextChildChild")
.align(Alignment.Center)
.fontSize(40)
.fontWeight(FontWeight.Bold)
}
}
}
@Component
struct Child {
@ObjectLink a: ClassA
build() {
Column() {
Text(this.a.c + "Child")
.align(Alignment.Center)
.fontSize(40)
.fontWeight(FontWeight.Bold)
Button('count - costOfOneAttempt')
.margin(15)
.onClick(() => {
this.a.c--
})
}
}
}
var nextID: number = 0
@Observed
class ClassA {
public name: string
public c: number
public id: number
constructor(c: number, name: string = 'OK') {
this.name = name
this.c = c
this.id = nextID++
}
}
以上就是关于鸿蒙ArkTS装饰器@Prop、@Link、@Provide和@Consume详解相关的全部内容,希望对你有帮助。欢迎持续关注潘子夜个人博客(www.panziye.com),学习愉快哦!