鸿蒙应用开发中,必然涉及到组件化开发,组件化开发就需要使用到组件间的通信,那么这篇文章所提到的三个装饰器就是在使用鸿蒙V1版装饰器中,实现组件化开发必备的神器,那么废话不多说,下面直接上干货。
状态变量@State
注意点:
@State 装饰器是V1版本开发中的状态变量修饰符,顾名思义,被@State修饰的变量,它的值改变可以触发UI界面的更新,在使用过程中有两点注意:
1、在使用时必须给类型和初始值,否者编译器就直接报错了;
2、@State修饰嵌套数据时无法监听到深层数据的变化,需要监听深层数据变化,就需要用到@Observed和@ObjectLink去配合使用
使用示例:
在以下案例中@State修饰message,当按下按钮时,Text显示的文字会随着,nessage的值变而刷新UI
@Entry
@Component
struct StatePage {
// 状态变量
@State message: string = '我是状态变量';
build() {
Column({ space: 20 }) {
Text(this.message)
.fontSize(30)
.fontWeight(FontWeight.Bold)
.margin({ top: 20 })
Button('修改状态变量')
.fontSize(30)
.fontWeight(FontWeight.Bold)
.onClick(() => {
this.message = '状态变量被修改了';
console.log('修改后:' + this.message)
})
}
.justifyContent(FlexAlign.Center)
.height('100%')
.width('100%')
}
}
效果如下:
以下效果可以看出,打印的message值变了,UI界面也随着改变了
若message这个变量没有被@State修饰的话,message的值会变,而UI界面不会刷新,效果如下:
父传子单向@Prop
注意点:
在使用组件通信时,是以传参的形式将变量传递到子组件,父组件传递的变量名和子组件接收的变量名必须同名,没有@Prop修饰时,也可以传值,但是传递的值,不会随着父组件的值变化而刷新UI,@Prop 修饰的是子组件的变量,@Prop修饰之后,由父组件传到子组件的变量值会随着父组件的值改变而刷新UI,@Prop可以给初始值,也可以不给初始值,但是必需确定类型,初始值会被父组件传递过来的值所覆盖。
使用示例:
在这个案例中,父组件中引入了Son这个子组件,并传递了一个message给子组件,这个子组件使用@Prop接收了message并显示
@Entry
@Component
struct PropPage {
@State message: string = 'Hello World';
build() {
Column({ space: 20 }) {
Son({ message: this.message })
Button('点我修改父传子的值')
.onClick(() => {
this.message = 'Welcome';
console.log('修改后:' + this.message);
})
}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
}
}
@Component
struct Son {
// 刷新UI
@Prop message: string
build() {
Column() {
Text(this.message)
.fontSize(30)
.fontWeight(FontWeight.Bold)
}
.backgroundColor('#10D169')
.width(200)
.justifyContent(FlexAlign.Center)
.height(200)
}
}
效果示例:
当点击父组件中的按钮,直接修改message的值时,子组件中显示的值也会被改变,并且刷新UI
当子组件接收的值不使用@Prop接收时,message值会变,但是UI并不会刷新:
父子双向@Link
注意点:
子组件接收的值使用@Link修饰时,当子组件主动修改变量的值时,父组件中的值也会跟着改变,并且刷新UI,使用@Link修饰的变量不能给初始值,不然编译器会直接报错
使用示例:
在这个案例中子组件LinkSon使用@Link接收了来自父组件的message,无论是子组件的数据改变还是父组件的数据改变都会触发数据的更新
@Entry
@Component
struct LinkPage {
@State message: string = '传到子组件的值';
build() {
Column({ space: 20 }) {
LinkSon({ message: this.message })
Button('点我修改父传子的值')
.onClick(() => {
this.message = 'Welcome';
console.log('修改后:' + this.message);
})
}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
}
}
@Component
struct LinkSon {
// 同步父组件UI刷新
@Link message: string
build() {
Column({ space: 20 }) {
Text(this.message)
.fontSize(20)
.fontWeight(FontWeight.Bold)
Button('修改父传子的值')
.onClick(() => {
this.message = '改掉了Message';
console.log('修改后:' + this.message);
})
}
.backgroundColor('#10D169')
.width(200)
.justifyContent(FlexAlign.Center)
.height(200)
}
}
效果示例:
在这个案例中,无论是点击子组件中的按钮改变message的值都可以触发界面上的UI更新