在ArkTS(HarmonyOS的TypeScript开发框架)中,组件间通信是构建复杂用户界面时一个非常重要的主题。组件间通信可以分为父子组件通信、兄弟组件通信以及跨层级组件通信等几种类型。下面我们将详细探讨每种类型的实现方式,并提供代码示例。
父组件可以通过props
将数据传递给子组件。子组件通过定义props
接口来接收这些数据。
代码示例:
// 子组件 ChildComponent.ts
import { Component, Prop } from '@arkui/arkts';
@Component
export default class ChildComponent extends ArkObject {
@Prop() message: string;
render() {
return (
<div>{this.message}</div>
);
}
}
// 父组件 ParentComponent.ts
import { Component } from '@arkui/arkts';
import ChildComponent from './ChildComponent';
@Component
export default class ParentComponent extends ArkObject {
private parentMessage = 'Hello from Parent!';
render() {
return (
<div>
<ChildComponent message={this.parentMessage} />
</div>
);
}
}
子组件可以通过事件触发的方式将数据传递给父组件。父组件通过监听子组件的事件来获取数据。
代码示例:
// 子组件 ChildComponent.ts
import { Component, Prop, Emit } from '@arkui/arkts';
@Component
export default class ChildComponent extends ArkObject {
@Prop() initialCount: number;
@Emit('countUpdated') emitCountUpdated(newCount: number) {}
private updateCount() {
const newCount = this.initialCount + 1;
this.emitCountUpdated(newCount);
}
render() {
return (
<button onClick={() => this.updateCount()}>Increase Count</button>
);
}
}
// 父组件 ParentComponent.ts
import { Component } from '@arkui/arkts';
import ChildComponent from './ChildComponent';
@Component
export default class ParentComponent extends ArkObject {
private count = 0;
onCountUpdated(newCount: number) {
this.count = newCount;
}
render() {
return (
<div>
<p>Current Count: {this.count}</p>
<ChildComponent initialCount={this.count} countUpdated={(newCount) => this.onCountUpdated(newCount)} />
</div>
);
}
}
兄弟组件之间不能直接通信,通常需要借助父组件作为中介。父组件通过props
和事件监听的方式,将数据从一个兄弟组件传递到另一个兄弟组件。
代码示例:
// 父组件 ParentComponent.ts
import { Component } from '@arkui/arkts';
import SiblingA from './SiblingA';
import SiblingB from './SiblingB';
@Component
export default class ParentComponent extends ArkObject {
private sharedData = '';
onSharedDataChanged(newData: string) {
this.sharedData = newData;
}
render() {
return (
<div>
<SiblingA onDataChanged={(data) => this.onSharedDataChanged(data)} />
<SiblingB sharedData={this.sharedData} />
</div>
);
}
}
// 兄弟组件 A (SiblingA.ts)
import { Component, Emit } from '@arkui/arkts';
@Component
export default class SiblingA extends ArkObject {
@Emit('dataChanged') emitDataChanged(data: string) {}
private sendData() {
this.emitDataChanged('Data from Sibling A');
}
render() {
return (
<button onClick={() => this.sendData()}>Send Data to Sibling B</button>
);
}
}
// 兄弟组件 B (SiblingB.ts)
import { Component, Prop } from '@arkui/arkts';
@Component
export default class SiblingB extends ArkObject {
@Prop() sharedData: string;
render() {
return (
<div>Received Data: {this.sharedData}</div>
);
}
}
对于跨层级组件通信,推荐使用状态管理工具或事件总线(Event Bus)。以下是一个简单的事件总线实现。
// EventBus.ts
class EventBus {
private static instance: EventBus;
private events: Record<string, Array<(data: any) => void>> = {};
private constructor() {}
public static getInstance(): EventBus {
if (!EventBus.instance) {
EventBus.instance = new EventBus();
}
return EventBus.instance;
}
public $on(event: string, callback: (data: any) => void): void {
if (!this.events[event]) {
this.events[event] = [];
}
this.events[event].push(callback);
}
public $emit(event: string, data?: any): void {
if (this.events[event]) {
this.events[event].forEach((callback) => callback(data));
}
}
public $off(event: string, callback?: (data: any) => void): void {
if (callback && this.events[event]) {
this.events[event] = this.events[event].filter((cb) => cb !== callback);
} else {
delete this.events[event];
}
}
}
export default EventBus.getInstance();
// 组件 A 发送事件
import EventBus from './EventBus';
function sendEvent() {
EventBus.$emit('customEvent', 'Data from Component A');
}
// 组件 B 接收事件
import EventBus from './EventBus';
function setupEventListener() {
EventBus.$on('customEvent', (data) => {
console.log('Received:', data); // 输出 "Data from Component A"
});
}
props
和事件机制实现。如果项目复杂度较高,建议引入状态管理工具(如Pinia或Redux),以更好地管理和同步全局状态。