鸿蒙开发:父组件如何调用子组件中的方法?
前言 本文基于Api13 很多的场景下,父组件需要触发子组件中的某个方法,来实现一些特定的逻辑,但是ArkUI是声明式UI,不能直接调用子组件中的方法,那么怎么去实现这个功能呢? 举一个很常见的案例,通过调用子组件中的某个方法,实现子组件UI的更新,简单的代码如下,只有通过调用changeUI方法,才会触发UI的更新。 @Component struct Child { @State message: string = "我是子组件" /** *AUTHOR:AbnerMing *INTRODUCE:子组件方法 */ changeUI() { this.message = "子组件UI更新了" } build() { Text(this.message) .width("100%") .height(50) .backgroundColor(Color.Pink) .textAlign(TextAlign.Center) } } 方式一:@Watch装饰器 如果你是用的V1版本装饰器,我们可以使用@Watch装饰器很轻松进行实现。 子组件定义@Watch装饰器 @Component struct Child { @State message: string = "我是子组件" @Prop @Watch("changeUI") isChangeStatus: boolean = false /** *AUTHOR:AbnerMing *INTRODUCE:子组件方法 */ changeUI() { this.message = "子组件UI更新了" } build() { Text(this.message) .width("100%") .height(50) .backgroundColor(Color.Pink) .textAlign(TextAlign.Center) } } 父组件调用 可通过子组件定义的isChangeStatus属性,不断的变化其值就可以了。 @Entry @Component struct DemoPage { @State isChangeStatus: boolean = false build() { Column() { Child({ isChangeStatus: this.isChangeStatus }) Button("点击") .onClick(() => { this.isChangeStatus = !this.isChangeStatus }) } .height('100%') .width('100%') .justifyContent(FlexAlign.Center) } } 方式二:@Monitor装饰器 和方式一的实现方式是一致的,只不过,@Monitor装饰器是V2版本,也就是说,你使用的是V2版本装饰器的话,可以使用这个。 子组件定义@Monitor装饰器 @ComponentV2 struct Child { @Local message: string = "我是子组件" @Param isChangeStatus: boolean = false /** *AUTHOR:AbnerMing *INTRODUCE:子组件方法 */ @Monitor("isChangeStatus") changeUI() { this.message = "子组件UI更新了" } build() { Text(this.message) .width("100%") .height(50) .backgroundColor(Color.Pink) .textAlign(TextAlign.Center) } } 父组件调用 @Entry @ComponentV2 struct DemoPage { @Local isChangeStatus: boolean = false build() { Column() { Child({ isChangeStatus: this.isChangeStatus }) Button("点击") .onClick(() => { this.isChangeStatus = !this.isChangeStatus }) } .height('100%') .width('100%') .justifyContent(FlexAlign.Center) } } 方式三:接口回调 定义回调函数 class ChangeController { change = () => {} } 子组件实现回调 @Component struct Child { @State message: string = "我是子组件" changeController: ChangeController = new ChangeController() aboutToAppear(): void { if (this.changeController.change != undefined) { this.changeController.change = () => { this.changeUI() } } } /** *AUTHOR:AbnerMing *INTRODUCE:子组件方法 */ changeUI() { this.message = "子组件UI更新了" } build() { Text(this.message) .width("100%") .height(50) .backgroundColor(Color.Pink) .textAlign(TextAlign.Center) } } 父组件调用函数 @Entry @Component struct DemoPage { changeController: ChangeController = new ChangeController() build() { Column() { Child({ changeController: this.changeController }) Button("点击") .onClick(() => { this.changeController.change() }) } .height('100%') .width('100%') .justifyContent(FlexAlign.Center) } } 方式四:事件订阅EventHub 订阅事件 @Component struct Child { @State message: string = "我是子组件" aboutToAppear(): void { getContext().eventHub.on("changeUI", ()=>{ this.changeUI() }) } /** *AUTHOR:AbnerMing *INTRODUCE:子组件方法 */ changeUI() { this.message = "子组件UI更新了" } build() { Text(this.message) .width("100%") .height(50) .backgroundColor(Color.Pink) .textAlign(TextAlign.Center) } } 触发事件 @Entry @Component struct DemoPage { build() { Column() { Child() Button("点击") .onClick(() => { getContext().eventHub.emit('changeUI') }) } .height('100%') .width('100%') .justifyContent(FlexAlign.Center) } } 相关总结 也许大家可能会有疑问,子组件更新UI,直接由装饰器触发不就行了,希望大家能够明白,以上呢只是简单的案例,在实际的开发中,子组件方法中可能很多的逻辑,比如网络请求,比如数据存储等等,并不是简单的UI更新。 当然了,所举的实现方式也不是全的,可能也有着其它的方式可以实现,大家在实际的开发中选择适合的一种即可。

前言
本文基于Api13
很多的场景下,父组件需要触发子组件中的某个方法,来实现一些特定的逻辑,但是ArkUI是声明式UI,不能直接调用子组件中的方法,那么怎么去实现这个功能呢?
举一个很常见的案例,通过调用子组件中的某个方法,实现子组件UI的更新,简单的代码如下,只有通过调用changeUI方法,才会触发UI的更新。
@Component
struct Child {
@State message: string = "我是子组件"
/**
*AUTHOR:AbnerMing
*INTRODUCE:子组件方法
*/
changeUI() {
this.message = "子组件UI更新了"
}
build() {
Text(this.message)
.width("100%")
.height(50)
.backgroundColor(Color.Pink)
.textAlign(TextAlign.Center)
}
}
方式一:@Watch装饰器
如果你是用的V1版本装饰器,我们可以使用@Watch装饰器很轻松进行实现。
子组件定义@Watch装饰器
@Component
struct Child {
@State message: string = "我是子组件"
@Prop @Watch("changeUI") isChangeStatus: boolean = false
/**
*AUTHOR:AbnerMing
*INTRODUCE:子组件方法
*/
changeUI() {
this.message = "子组件UI更新了"
}
build() {
Text(this.message)
.width("100%")
.height(50)
.backgroundColor(Color.Pink)
.textAlign(TextAlign.Center)
}
}
父组件调用
可通过子组件定义的isChangeStatus属性,不断的变化其值就可以了。
@Entry
@Component
struct DemoPage {
@State isChangeStatus: boolean = false
build() {
Column() {
Child({ isChangeStatus: this.isChangeStatus })
Button("点击")
.onClick(() => {
this.isChangeStatus = !this.isChangeStatus
})
}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
}
}
方式二:@Monitor装饰器
和方式一的实现方式是一致的,只不过,@Monitor装饰器是V2版本,也就是说,你使用的是V2版本装饰器的话,可以使用这个。
子组件定义@Monitor装饰器
@ComponentV2
struct Child {
@Local message: string = "我是子组件"
@Param isChangeStatus: boolean = false
/**
*AUTHOR:AbnerMing
*INTRODUCE:子组件方法
*/
@Monitor("isChangeStatus")
changeUI() {
this.message = "子组件UI更新了"
}
build() {
Text(this.message)
.width("100%")
.height(50)
.backgroundColor(Color.Pink)
.textAlign(TextAlign.Center)
}
}
父组件调用
@Entry
@ComponentV2
struct DemoPage {
@Local isChangeStatus: boolean = false
build() {
Column() {
Child({ isChangeStatus: this.isChangeStatus })
Button("点击")
.onClick(() => {
this.isChangeStatus = !this.isChangeStatus
})
}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
}
}
方式三:接口回调
定义回调函数
class ChangeController {
change = () => {}
}
子组件实现回调
@Component
struct Child {
@State message: string = "我是子组件"
changeController: ChangeController = new ChangeController()
aboutToAppear(): void {
if (this.changeController.change != undefined) {
this.changeController.change = () => {
this.changeUI()
}
}
}
/**
*AUTHOR:AbnerMing
*INTRODUCE:子组件方法
*/
changeUI() {
this.message = "子组件UI更新了"
}
build() {
Text(this.message)
.width("100%")
.height(50)
.backgroundColor(Color.Pink)
.textAlign(TextAlign.Center)
}
}
父组件调用函数
@Entry
@Component
struct DemoPage {
changeController: ChangeController = new ChangeController()
build() {
Column() {
Child({ changeController: this.changeController })
Button("点击")
.onClick(() => {
this.changeController.change()
})
}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
}
}
方式四:事件订阅EventHub
订阅事件
@Component
struct Child {
@State message: string = "我是子组件"
aboutToAppear(): void {
getContext().eventHub.on("changeUI", ()=>{
this.changeUI()
})
}
/**
*AUTHOR:AbnerMing
*INTRODUCE:子组件方法
*/
changeUI() {
this.message = "子组件UI更新了"
}
build() {
Text(this.message)
.width("100%")
.height(50)
.backgroundColor(Color.Pink)
.textAlign(TextAlign.Center)
}
}
触发事件
@Entry
@Component
struct DemoPage {
build() {
Column() {
Child()
Button("点击")
.onClick(() => {
getContext().eventHub.emit('changeUI')
})
}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
}
}
相关总结
也许大家可能会有疑问,子组件更新UI,直接由装饰器触发不就行了,希望大家能够明白,以上呢只是简单的案例,在实际的开发中,子组件方法中可能很多的逻辑,比如网络请求,比如数据存储等等,并不是简单的UI更新。
当然了,所举的实现方式也不是全的,可能也有着其它的方式可以实现,大家在实际的开发中选择适合的一种即可。