【鸿蒙】跨组件通信,父子组件互相调用传值

包括emitter、eventHub以及基于

@Provide、@Consume、(跨组件后代组件,双向同步,类似@Link,@Link父子组件)

@Watch的响应式数据流(监听数据变化)

参考官方文档:
【状态管理最佳实践】
https://developer.huawei.com/consumer/cn/doc/best-practices-V5/bpta-status-management-V5
【EventHub】
https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-inner-application-eventhub-V5
【emitter】
https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-emitter-V5#emitteron

1、自定义事件调度器(eventHub)

import { NavigationBar } from "../components/navigationBar";


@Builder
export function FourPageBuilder(name: string, param: Object) {
  FourPage()
}

// 1、创建一个事件分发器
class EventDispatcher {
  static childCallback?: (value: number) => void;

  static dispatchToChild(value: number) {
    if (EventDispatcher.childCallback) {
      EventDispatcher.childCallback(value);
    }
  }
}

@Entry
@Component
struct FourPage {
  @State message: string = 'Hello World';

  build() {
    NavDestination(){
      NavigationBar({ title: '测试' })
      Button('调用子组件方法').onClick(() => {
        // 3、发送事件
        EventDispatcher.dispatchToChild(100);
      });
      ChildComponent()
    }.hideTitleBar(true)
  }
}

@Component
struct ChildComponent {
  @State value: string = ""

  aboutToAppear(): void {
    // 2、在子组件或父组件中添加订阅事件
    EventDispatcher.childCallback = (value: number) => {
      this.handleChildMethod(value);
    };
  }

  handleChildMethod(value: number) {
    console.info('我是子组件方法', '父组件传递的值为:' + value);
    this.value = String(value)
  }

  build() {
    Text('我是子组件,收到父组件传值:' + this.value)
  }
}

2、emitter(订阅事件)

// 订阅
// 1、定义一个eventId为1的事件
let event: emitter.InnerEvent = {
    eventId: 1
};
// 2、收到eventId为1的事件后执行该回调
let callback = (eventData: emitter.EventData): void => {
    console.log('收到事件:', JSON.stringify(eventData))
};
// 3、订阅eventId为1的事件
emitter.on(event, callback)


// 发送事件(在不同组件或页面中)
// 1、定义一个eventId为1的事件,事件优先级为Low
let event: emitter.InnerEvent = {
    eventId: 1,
    priority: emitter.EventPriority.LOW
};
// 2、发送eventId为1的事件的数据
let eventData: emitter.EventData = {
    data: {
        content: 'c',
        id: 1,
        isEmpty: false
    }
};
// 3、发送eventId为1的事件,事件内容为eventData
emitter.emit(event, eventData);

或者简写:

// 订阅事件
emitter.on('test', () => {
    // 不需要数据
})
emitter.on('test', (eventData: emitter.EventData) => {
    console.log('收到数据:', JSON.stringify(eventData))
})
// 发送事件
emitter.emit('test');
emitter.emit('test', {
    data: {
        id: 1,
        isEmpty: false,
        content: '数据内容'
    }
} as emitter.EventData);

3、eventHub

eventHub是另一种事件管理机制,它允许组件间通过事件名来进行通信。相比前两种方法,它可能更接近Vue.js的事件总线模式。

@Component
struct ChildComponent {
  @State value :number = -1
  aboutToAppear(): void {
    getContext(this).eventHub.on('1', (data: number) => {
      this.handleChildMethod(data as number);
    });
  }
 
  handleChildMethod(value: number) {
    console.info('我是子组件方法', '父组件传递的值为:' + value);
    this.value = value
  }
 
  build() {
    Column() {
      Text(`我是子组件,父组件传递的值为:${this.value}`)
    }.width('100%');
  }
}
 
@Entry
@Component
struct Index {
  build() {
    Column() {
      Button('调用子组件方法').onClick(() => {
        getContext(this).eventHub.emit('1', 33);
      });
 
      ChildComponent();
    }
    .width('100%');
  }
}

4、基于@Provide、@Consume、@Watch的数据共享

对于更高级的数据共享需求,HarmonyOS 提供了@Provide、@Consume和@Watch注解。这些注解可以用来在父子组件间共享状态,并且可以监听状态变化来自动更新UI。

@Component
struct Page012Child {
  @Consume @Watch('onDataChanged') array: Array<Object>
  @Consume @Watch('onDataChanged') index: number
 
  build() {
    Column() {
      Text(`array:${JSON.stringify(this.array)}`)
      Text(`index:${this.index}`)
      Text(`每次this.index变化时,自定义onDataChanged方法会回调,注意首次不会回调`)
    }
  }
 
  onDataChanged() {
    console.info('====onDataChanged')
  }
}
 
@Entry
@Component
struct Page012 {
  @Provide array: Array<Object> = new Array<Object>()
  @Provide index: number = 0
 
  build() {
    Column() {
      Button('测试').onClick(() => {
        this.array.push("abc")
        this.index++
      })
 
      Page012Child()
    }
    .width('100%')
    .height('100%')
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值