目录
- HarmonyOS Next 状态管理:Local 装饰器实践
- HarmonyOS Next 状态管理:Param 装饰器实践
- HarmonyOS Next 状态管理:Once 装饰器实践
- HarmonyOS Next 状态管理:Event 装饰器实践
- HarmonyOS Next 状态管理:!! 状态装饰器实践
- HarmonyOS Next 状态管理:@ObserverV2和@Trace 装饰器实践
- HarmonyOS Next 状态管理:Provider和Consumer 装饰器实践
- HarmonyOS Next 状态管理:Monitor 装饰器实践
- HarmonyOS Next 状态管理:Computed 装饰器实践
- # HarmonyOS Next 状态管理:Type 装饰器实践
一. @Event 修饰器概述
在日常开发中,父子组件之间的数据同步是一个常见需求。虽然可以通过 @Param
结合回调函数实现父子组件的同步刷新,但这种方式较为繁琐。为此,@Event
修饰器应运而生,专门用于简化事件传递和数据同步。
二、@Event 修饰器的限制
使用范围:
- @Event
只能在 ComponentV2
中使用。
修饰范围:
- @Event
只能修饰回调方法,不能与其他变量搭配使用。相比之下,@Param
既可以修饰回调方法,也可以修饰变量。
三、实践探索
3.1 @Event的简单使用
@Entry
@ComponentV2
struct Index {
@Local msg: string = "x"
build() {
Column({space: 20}) {
Text(this.msg)
Button('change value')
.onClick(() => {
this.msg += `abc`
})
Line().width('100%').height(1).backgroundColor(Color.Gray)
ChildComponent({cMsg: this.msg, changeValueCallback: () => {
this.msg += `${Math.round(Math.random() * 100)}`
}, changeMsgCallback: (msg: string) => {
this.msg = msg
}})
}
}
}
@ComponentV2
struct ChildComponent {
@Param cMsg: string = ""
@Event changeValueCallback: () => void
@Event changeMsgCallback: (msg: string) => void
build() {
Column({space: 12}) {
Text(this.cMsg)
Button('调用changeValueCallback')
.onClick(() => {
this.changeValueCallback()
})
Button('调用changeMsgCallbackk')
.onClick(() => {
this.changeMsgCallback(`${Date().toString()}`)
})
}
}
}
关键点:
- 回调方法的使用:子组件无法直接修改
cMsg
的值,但可以通过@Event
修饰的回调方法间接修改父组件的状态。 - 事件传递:
@Event
提供了一种简洁的方式,用于在父子组件之间传递事件并同步数据。
3.2 @Event 装饰可选方法
@Event
同样可以装饰可选方法,例子如下:
@Entry
@ComponentV2
struct Index {
@Local name: string = "name"
build() {
Column({space: 20}) {
Text(this.name)
Line().width('100%').height(1).backgroundColor(Color.Gray)
ChildComponent({cName: this.name, changeNameCallback: (name: string) => {
this.name = name
}})
}
}
}
@ComponentV2
struct ChildComponent {
@Param cName: string = "cName"
@Event changeNameCallback?: (name: string) => void
build() {
Column({space: 12}) {
Text(`cName:${this.cName}`)
.onClick(() => {
this.changeNameCallback!(`${Date().toString()}`)
})
}
}
}
关键点:
- 可选回调:
@Event
可以修饰可选回调方法,增强了代码的灵活性。 - 空值处理:在调用可选回调方法时,需确保其存在(如使用
!
强制解包)。
3.3 @Event 更新父子组件时机
@Entry
@ComponentV2
struct Index {
@Local name: string = "name"
build() {
Column({space: 20}) {
Text(this.name)
Line().width('100%').height(1).backgroundColor(Color.Gray)
ChildComponent({cName: this.name, changeNameCallback: (name: string) => {
this.name = name
console.log(`callback called in father component:${this.name}`)
}})
}
}
}
@ComponentV2
struct ChildComponent {
@Param cName: string = "cName"
@Event changeNameCallback?: (name: string) => void
build() {
Column({space: 12}) {
Text(`cName:${this.cName}`)
.onClick(() => {
if (this.changeNameCallback) {
this.changeNameCallback(`${Date().toString()}`)
console.log(`callback called in subcomponent: ${this.cName}`)
}
})
}
}
}
控制台输出
callback called in father component:Sun Mar 02 2025 09:39:27 GMT+0800
callback called in subcomponent: name
关键点:
- 同步机制:通过
@Event
修饰的回调方法修改父组件的值是立即生效的,但从父组件同步回子组件的过程是异步的。因此,在调用@Event
方法后,子组件中的值不会立即更新。 - 异步更新:这种设计避免了频繁的同步操作,提升了性能,但开发者需注意数据更新的时机。
四、总结
通过以上实践,我们可以得出以下结论:
- 事件传递:
@Event
提供了一种简洁的方式,用于在父子组件之间传递事件并同步数据。 - 灵活性:
@Event
支持修饰可选回调方法,增强了代码的灵活性。 - 异步更新:父组件状态的更新是立即生效的,但子组件的更新是异步的,开发者需注意数据同步的时机。
@Event
修饰器的引入,极大地简化了父子组件之间的数据同步和事件传递,提升了代码的可读性和可维护性。在实际开发中,合理使用 @Event
可以有效减少冗余代码,提高开发效率。