包括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%')
}
}