MessageBus 通信组件库
项目简介
MessageBus
是一个基于 postMessage
实现的跨窗口、跨域通信组件库,适用于父子页面、iframe 间的消息传递。支持 Promise 回调、上下文隔离,确保通信的可靠性和安全性。适用于多种 Web 环境,能够简化不同页面间的通信复杂度,尤其在跨域时能够确保消息的安全传递。
特性
- ✅ 跨域通信:支持不同窗口(包括 iframe 和父页面)之间的安全通信。
- ✅ 自动 Promise 回调:通过 Promise 机制处理回调,简化异步操作。
- ✅ 上下文隔离:每个 MessageBus 实例通过上下文(
context
)隔离不同场景的消息传递,避免干扰。 - ✅ 组件化封装:支持 React 和 Vue 组件版本,便于集成到各类现代前端项目中。
- ✅ 方法注册与调用:通过
register
方法注册可调用的函数,通过callParent
方法调用父页面方法并获取返回值。
1. 安装和使用
1.1. 引入 post-message-bus.js
首先,引入 post-message-bus.js
文件,或者将其作为依赖安装到项目中。
通过 CDN 引入
<script src="https://cdn.example.com/post-message-bus.js"></script>
通过 npm/yarn 安装
npm install post-message-bus
2. 关键功能
2.1. 注册方法(register
)
父页面或子页面通过 register
方法注册可以被其他页面调用的函数。
用法示例:
在父页面中注册一个方法(比如更新表格数据):
// 在父页面中
const bus = new MessageBus('app');// 注册一个方法(比如更新表格数据)
bus.register('updateTable', ({ rowIndex, newValue }) => {console.log(`更新表格行:${rowIndex},新值:${newValue}`);return { success: true }; // 返回操作结果
});
2.2. 调用父页面方法(callParent
)
子页面可以通过 callParent
调用父页面上注册的方法,并获取返回的值。
用法示例:
在子页面中调用父页面的 updateTable
方法:
// 在子页面中
const bus = new MessageBus('app');// 调用父页面的 updateTable 方法
bus.callParent('updateTable', { rowIndex: 1, newValue: '更新的值' }).then(response => {console.log('父页面响应:', response);});
2.3. 跨窗口调用和返回
MessageBus
支持父页面与子页面、iframe 的通信,并且通过 postMessage
保证了消息传递的安全性。
3. 实际使用场景
3.1. 父页面到子页面的通信
父页面代码:
<!DOCTYPE html>
<html lang="en">
<head><title>父页面</title></head>
<body><h2>父页面</h2><iframe src="child.html" width="100%" height="300"></iframe><script src="post-message-bus.js"></script><script>const bus = new MessageBus('app');// 注册父页面的 updateTable 方法bus.register('updateTable', ({ rowIndex, newValue }) => {console.log('父页面收到更新:', rowIndex, newValue);return { success: true }; // 返回成功信息});</script>
</body>
</html>
子页面代码:
<!DOCTYPE html>
<html lang="en">
<head><title>子页面</title></head>
<body><h2>子页面</h2><button onclick="update()">调用父页面方法</button><script src="post-message-bus.js"></script><script>const bus = new MessageBus('app');// 子页面调用父页面的 updateTable 方法function update() {bus.callParent('updateTable', { rowIndex: 1, newValue: '子页面的更新值' }).then(response => {console.log('父页面响应:', response);});}</script>
</body>
</html>
3.2. React 组件化版本
在 React 中使用 MessageBus
组件,可以实现父子组件之间的通信。
组件化示例:
cd vite-react
npm install && npm run dev
import React, { useEffect } from 'react';
import './post-message-bus.js';const bus = new MessageBus('react-app');function App() {useEffect(() => {// 注册可以被调用的方法bus.register('greet', ({ name }) => {return `Hello, ${name} from React!`;});}, []);return <div>React 组件已启动,等待消息调用</div>;
}export default App;
3.3. Vue 组件化版本
在 Vue3 中也可以很容易地集成 MessageBus
,实现与父页面的通信。
组件化示例:
cd vite-vue
npm install && npm run dev
<template><div>Vue 组件,已注册消息监听</div>
</template><script setup>
const bus = new window.MessageBus('vue-app');// 注册一个简单的方法
bus.register('ping', () => 'pong from Vue');
</script>
4. API 详细说明
4.1. MessageBus 类
构造函数
new MessageBus(context = 'default')
context
: 可选,用于区分不同的通信实例,确保在不同场景下消息传递互不干扰。
register
方法
bus.register(method, handler)
method
: 方法名称,子页面或其他组件会调用该方法。handler
: 回调函数,当方法被调用时执行,并返回结果。
callParent
方法
bus.callParent(method, params = {})
method
: 调用父页面的方法名。params
: 调用方法时传递的参数。
返回一个 Promise,接收父页面返回的结果。
_onMessage
方法
- 内部方法,用于监听来自其他窗口、iframe 的消息,并根据消息类型进行处理。
5. 安全性说明
同源策略
postMessage
默认遵循同源策略,仅允许与当前页面相同 origin
的页面进行通信。如果要跨域通信,可以显式指定 origin
,例如:
postMessage(data, 'http://example.com')
6. 构建和启动步骤
React 组件版本
- 进入
vite-react
目录 - 安装依赖:
npm install
- 启动开发服务器:
npm run dev
Vue 组件版本
- 进入
vite-vue
目录 - 安装依赖:
npm install
- 启动开发服务器:
npm run dev
7. 总结
MessageBus
是一种跨页面、跨窗口的安全通信工具,能够简化现代 Web 项目中的父子页面、iframe 等组件间的通信。它提供了清晰的 API、易于集成的组件化版本,并能确保不同页面之间的消息传递不受干扰。
使用场景
- 父子页面通信:例如,父页面控制子页面的行为,或者子页面需要从父页面获取数据。
- 跨域通信:在不同域名、不同窗口之间安全地传递消息。
- React 和 Vue 项目中的组件通信:用于各类前端框架的组件间异步通信。