postmessage-duplexpostmessage-duplex
首页
指南
API
示例
🎮 Playground
  • FAQ
  • 更新日志
  • GitHub
  • 简体中文
  • English
GitHub
首页
指南
API
示例
🎮 Playground
  • FAQ
  • 更新日志
  • GitHub
  • 简体中文
  • English
GitHub
  • 示例

    • 示例
    • 基础示例
    • Vue 集成
    • React 集成
    • 高级用法

示例

本节提供各种使用场景的完整代码示例。

推荐

想要快速体验?试试 🎮 在线 Playground - 无需安装,直接在浏览器中体验!

示例列表

示例描述
基础示例iframe 和 Service Worker 的基本使用
Vue 集成Vue 2/3 组件中的使用
React 集成React 组件和 Hooks
高级用法错误处理、类型安全、性能优化

在线演示

启动本地开发服务器查看演示:

# 克隆仓库
git clone https://github.com/ljquan/postmessage-duplex.git
cd postmessage-duplex

# 安装依赖
npm install

# 启动开发服务器
npm run dev

# 访问演示页面
open http://localhost:7100/demo/

演示页面

Iframe 演示

  • 基础通讯: /demo/iframe/index.html
    • 父子页面双向通讯
    • 请求-响应模式演示
    • 超时处理演示

Service Worker 演示

  • SW 通讯: /demo/service-worker/index.html
    • 页面与 SW 双向通讯
    • 数据缓存演示

调试器

  • 消息调试: /demo/debugger/index.html
    • 实时查看消息
    • 手动发送测试消息
    • 通道状态监控

快速代码片段

最简 Iframe 通讯

// 父页面
const channel = new IframeChannel(document.querySelector('iframe'))
const { data } = await channel.publish('getData', { id: 1 })

// 子页面
const channel = new IframeChannel(location.origin)
channel.subscribe('getData', ({ data }) => ({ result: data.id * 2 }))

最简 Service Worker 通讯

// 页面
const channel = await ServiceWorkerChannel.createFromPage()
await channel.publish('cache', { url: '/api/data' })

// sw.js
self.addEventListener('message', (e) => {
  const channel = ServiceWorkerChannel.createFromEvent(e)
  channel.subscribe('cache', async ({ data }) => {
    await caches.open('v1').then(c => c.add(data.url))
    return { cached: true }
  })
})

类型安全调用

interface Methods {
  getUser(p: { id: number }): { name: string }
}

const channel = new IframeChannel<Methods>(iframe)
const response = await channel.call('getUser', { id: 1 })
// response.data 类型: { name: string } | undefined

项目模板

创建新项目

# 使用 Vite 创建项目
npm create vite@latest my-app -- --template vanilla-ts

cd my-app
npm install postmessage-duplex

基础项目结构

my-app/
├── index.html          # 父页面
├── child.html          # 子页面 (iframe)
├── src/
│   ├── main.ts         # 父页面入口
│   ├── child.ts        # 子页面入口
│   └── channel.ts      # 通道封装
└── package.json

channel.ts 封装示例

// src/channel.ts
import { IframeChannel, ReturnCode, type PostResponse } from 'postmessage-duplex'

interface RemoteMethods {
  getData(params: { id: number }): { name: string }
  setData(params: { data: object }): void
}

export class ChannelClient {
  private channel: IframeChannel<RemoteMethods>
  
  constructor(iframe: HTMLIFrameElement) {
    this.channel = new IframeChannel(iframe)
  }
  
  async getData(id: number) {
    const response = await this.channel.call('getData', { id })
    this.checkResponse(response)
    return response.data!
  }
  
  async setData(data: object) {
    const response = await this.channel.call('setData', { data })
    this.checkResponse(response)
  }
  
  private checkResponse(response: PostResponse) {
    if (response.ret !== ReturnCode.Success) {
      throw new Error(response.msg || 'Request failed')
    }
  }
  
  destroy() {
    this.channel.destroy()
  }
}
在 GitHub 上编辑此页
上次更新: 2026/1/29 03:36
贡献者: liquidliang
Next
基础示例