【鸿蒙应用ArkTS开发系列】- 父组件直接调用子组件方法

今天这篇文档,讲的是鸿蒙应用开发中会遇到的一种常见场景,父组件显式调用子组件的方法

最近很多同学反馈,在鸿蒙ArkTS 应用开发过程中,在对页面的页面层级进行梳理,抽取子组件的时候,由于一些原先写在页面Page中的方法会定义到子组件component中去,但是有些场景需要在父组件中调用子组件的方法。

有些同学可能会考虑使用事件来进行处理,但是对于一些同步调用的场景,比如调用子组件的一个方法,然后同步返回一个数据,这种场景使用事件,无法实现,如果使用事件,定义双向事件接收数据,会使代码的可读性变差,也会使代码功能变得复杂。

下面介绍一种官方提供的父组件显式调用子组件的方法(官方文档中有提到,很多同学可能没有留意到)

**

1. 创建子组件ChildComponent

**

import { ChildComponentController } from './ChildComponentController';
@Component
export struct ChildComponent {
  @State message: string = 'Hello World From ChildComponent'
  public mCmpController: ChildComponentController = null;

  aboutToAppear() {
    if (this.mCmpController) {
      this.mCmpController.attach(this); //绑定控制器
    }
  }

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(25)
          .fontWeight(FontWeight.Bold)
      }
      .width('100%')
    }
    .height('100%')
    .backgroundColor(Color.Blue)
  }

  getName(): string {
    return 'my name is ChildComponent!';
  }
}

这里子组件ChildComponent 提供一个getName的方法提供父组件调用。

**

接下来我们为ChildComponent 创建组件控制器ChildComponentController

2. 创建组件控制器ChildComponentController

**

import { ChildComponent } from './ChildComponent';

export class ChildComponentController {
  private mComponent: ChildComponent = null;

  attach(component: ChildComponent) {
    this.mComponent = component;
  }

  public getName(): string {
    if (this.mComponent) {
      return this.mComponent.getName();
    }
    return '';
  }
}

子组件控制器提供了一个attach方法,通过该方法将其与组件进行绑定(实际上就是持有组件实例),通过上面代码我们知道,在子组件ChildComponent的aboutToAppear函数中,我们进行了attach的调用,那子组件需要一个控制器实例,这个控制器实例从哪里获取呢,其实就是父组件引用子组件的时候设置的。

子组件除了attach方法外,我们还看到了一个getName方法,这个方法只是一个代理方法,具体实现是在子组件中完成。

**
最后 在ParentComponent 创建ChildComponentController实例,使用控制器显式调用子组件的方法

3. 创建ChildComponentController实例,调用子组件的方法

**

import { ChildComponent } from './ChildComponent'
import { ChildComponentController } from './ChildComponentController';

@Component
export struct ParentComponent {
  @State message: string = ''
  private mChildComponentController: ChildComponentController = new ChildComponentController();

  build() {
    Row() {
      Column() {

        Column() {
          Text('ParentComponent')
            .fontSize(25)
            .fontWeight(FontWeight.Bold)
            
          Button("调用子组件方法")
            .width("80%")
            .height("50vp")
            .margin({ top: "10vp", bottom: '10vp' })
            .onClick(() => {
              this.message = this.mChildComponentController.getName();
            })
            
          Text(this.message)
            .fontSize(25)
        }
        .height('50%')
        .justifyContent(FlexAlign.Center)

        ChildComponent({ mCmpController: this.mChildComponentController })
          .height('50%')
      }
      .width('100%')
    }
    .height('100%')
  }
}

父组件ParentComponent 在build方法中引用ChildComponent的时候,
ChildComponent({ mCmpController: this.mChildComponentController })
将创建的ChildComponentController 设置到子组件中。子组件创建的时候将自身实例通过ChildComponentController 的attach进行绑定,父组件通过ChildComponentController 调用子组件的getName方法。

代码简简单单,希望能够解决同学们在实际开发中遇到的问题。

在这里插入图片描述

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
组件可以通过两种方法直接调用组件方法。 方案一是通过在组件中使用ref来直接调用组件方法。在组件的模板中,使用ref属性给组件命名,然后在组件方法中通过`this.$refs.child.methodName()`来调用组件方法。具体代码如下: ```javascript // 组件 <template> <div> <Button @click="handleClick">点击调用组件方法</Button> <Child ref="child"/> </div> </template> <script> import Child from './child'; export default { methods: { handleClick() { this.$refs.child.methodName(); }, }, } </script> // 组件 <template> <div> 我是组件 </div> </template> <script> export default { methods: { methodName() { console.log('我是组件方法'); }, }, }; </script> ``` 方案二是通过组件的emit和on方法来进行通信。在组件方法中,通过`this.$refs.child.$emit('eventName')`来触发组件方法执行,在组件中使用`this.$on('eventName', methodName)`来监听事件并执行相应的方法。具体代码如下: ```javascript // 组件 <template> <div> <Button @click="handleClick">点击调用组件方法</Button> <Child ref="child"/> </div> </template> <script> import Child from './child'; export default { methods: { handleClick() { this.$refs.child.$emit('eventName'); }, }, } </script> // 组件 <template> <div> 我是组件 </div> </template> <script> export default { mounted() { this.$nextTick(function() { this.$on('eventName', function() { console.log('我是组件方法'); }); }); }, }; </script> ``` 以上是两种组件直接调用组件方法方法,根据实际情况选择适合的方式进行调用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [vue 组件调用组件方法](https://blog.csdn.net/qq_29236119/article/details/113558032)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [组件如何调用组件中的方法?](https://blog.csdn.net/ni15534789894/article/details/120501674)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值