跨组件通信模式合集

本目录包含 7 种无第三方依赖 的跨组件通信模式实现。为了“保留各模式最合适的调用方式”,每种模式对外导出的 API 不强求一致(例如 EventBus 使用 on/emit,Store 使用 setState,ProxyStore 暴露 state)。


📋 模式总览

#模式核心文件文档特点最佳场景
1发布订阅SharedStateBridgeSingleton.tsREADME完全解耦,多对多通信工单系统、微前端
2观察者ObserverSingleton.tsREADME一对多依赖关系数据驱动更新
3事件总线EventBusSingleton.tsREADME简单直接,on/emit全局事件通知
4状态容器StoreSingleton.tsREADME状态快照,批量更新简单状态管理
5广播通道BroadcastSingleton.tsREADME跨标签页同步多标签页/iframe
6自定义事件CustomEventSingleton.tsREADME原生 DOM API跨框架通信
7代理模式ProxyStoreSingleton.tsREADME透明响应式操作Vue3/Valtio 风格

🔗 入口文件约定

每种模式都有一个 *Singleton.ts 作为默认入口(也会额外导出底层实例供高级用法)。


🎯 模式选择指南

┌─────────────────────────────────────────────────────────────────────┐
│                        如何选择通信模式?                            │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  需要跨浏览器标签页通信?                                            │
│     └── 是 → 广播通道 (BroadcastChannel)                             │
│                                                                      │
│  需要跨框架通信(React + Vue + Angular)?                           │
│     └── 是 → 自定义事件 (CustomEvent)                                │
│                                                                      │
│  需要透明响应式(类似 Vue3)?                                       │
│     └── 是 → 代理模式 (ProxyStore)                                   │
│                                                                      │
│  需要状态快照/批量更新?                                             │
│     └── 是 → 状态容器 (Store)                                        │
│                                                                      │
│  动态加载组件/微前端场景?                                           │
│     └── 是 → 发布订阅 (ServiceRequest)                               │
│                                                                      │
│  简单的全局事件通知?                                                │
│     └── 是 → 事件总线 (EventBus)                                     │
│                                                                      │
│  一对多的数据依赖关系?                                              │
│     └── 是 → 观察者 (Observer)                                       │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

📁 目录结构

Pattern/
├── README.md                          # 本文档
│
├── ServiceRequest/                    # 1. 发布订阅模式
│   ├── Registry.ts                    # 通用注册表
│   ├── SharedStateBridge.ts           # 发布订阅核心类
│   ├── SharedStateBridgeSingleton.ts  # 单例导出 ⭐
│   └── README.md                      # 使用文档
│
├── Observer/                          # 2. 观察者模式
│   ├── Subject.ts                     # 被观察者核心类
│   ├── ObserverSingleton.ts           # 单例导出 ⭐
│   └── README.md                      # 使用文档
│
├── EventBus/                          # 3. 事件总线
│   ├── EventBus.ts                    # 事件总线核心类
│   ├── EventBusSingleton.ts           # 单例导出 ⭐
│   └── README.md                      # 使用文档
│
├── Store/                             # 4. 状态容器
│   ├── Store.ts                       # 状态容器核心类
│   ├── StoreSingleton.ts              # 单例导出 ⭐
│   └── README.md                      # 使用文档
│
├── BroadcastChannel/                  # 5. 广播通道
│   ├── BroadcastBridge.ts             # 广播桥接核心类
│   ├── BroadcastSingleton.ts          # 单例导出 ⭐
│   └── README.md                      # 使用文档
│
├── CustomEvent/                       # 6. 自定义事件
│   ├── CustomEventBridge.ts           # 自定义事件核心类
│   ├── CustomEventSingleton.ts        # 单例导出 ⭐
│   └── README.md                      # 使用文档
│
└── ProxyStore/                        # 7. 代理模式
    ├── ProxyStore.ts                  # 代理存储核心类
    ├── ProxyStoreSingleton.ts         # 单例导出 ⭐
    └── README.md                      # 使用文档
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

📊 模式对比

功能对比

特性发布订阅观察者事件总线状态容器广播通道自定义事件代理模式
完全解耦⚠️
多对多通信
跨标签页
跨框架
状态缓存
状态快照
透明操作
一次性订阅

浏览器兼容性

模式ChromeFirefoxSafariEdgeIE
发布订阅
观察者
事件总线
状态容器
广播通道54+38+15.4+79+
自定义事件9+
代理模式49+18+10+12+

🔧 各模式详解

1️⃣ 发布订阅模式 (Pub/Sub)

📁 ServiceRequest/ | 📄 文档

核心文件

原理:通过中间调度中心解耦发布者和订阅者,支持多对多通信。

import {
  publishSharedData,
  subscribeSharedData
} from './ServiceRequest/SharedStateBridgeSingleton'

// 发布
publishSharedData('user.profile', { name: 'John' })

// 订阅
subscribeSharedData('user.profile', (data) => {
  console.log('Profile updated:', data)
})
1
2
3
4
5
6
7
8
9
10
11
12

2️⃣ 观察者模式 (Observer)

📁 Observer/ | 📄 文档

核心文件

原理:被观察者维护观察者列表,状态变化时直接通知所有观察者。

import { subject } from './Observer/ObserverSingleton'

const counter$ = subject<number>('counter')
counter$.attach((value) => console.log(value))
counter$.notify(10)
1
2
3
4
5

vs 发布订阅:观察者直接依赖被观察者,发布订阅通过中间调度。


3️⃣ 事件总线 (Event Bus)

📁 EventBus/ | 📄 文档

核心文件

原理:集中式事件管理,经典的 on/emit 模式。

import { on, emit, once } from './EventBus/EventBusSingleton'

// 一次性订阅
once('app:ready', () => {
  console.log('App initialized!')
})

emit('app:ready', true)

// 普通订阅
on('app:ready', (ready) => console.log('ready?', ready))
1
2
3
4
5
6
7
8
9
10
11

4️⃣ 状态容器 (Singleton Store)

📁 Store/ | 📄 文档

核心文件

原理:单例状态对象 + 订阅机制,支持状态快照和批量更新。

import { setState, getSnapshot, batchUpdate } from './Store/StoreSingleton'

// 批量更新
batchUpdate({
  'user.name': 'John',
  'user.age': 30,
  theme: 'dark'
})

// 单点更新
setState('user.name', 'John')

// 获取快照
console.log(getSnapshot())
1
2
3
4
5
6
7
8
9
10
11
12
13
14

5️⃣ 广播通道 (Broadcast Channel)

📁 BroadcastChannel/ | 📄 文档

核心文件

原理:浏览器原生 BroadcastChannel API,支持跨标签页通信。

import { publish, subscribe } from './BroadcastChannel/BroadcastSingleton'

// 标签页 A:发布
publish('session', { userId: 123 })

// 标签页 B:自动收到
subscribe('session', (session) => {
  console.log('Session synced:', session)
})
1
2
3
4
5
6
7
8
9

⚠️ 注意:仅同源页面可通信,不支持 IE。


6️⃣ 自定义事件 (Custom Events)

📁 CustomEvent/ | 📄 文档

核心文件

原理:原生 DOM CustomEvent + dispatchEvent。

import { dispatch, on } from './CustomEvent/CustomEventSingleton'

// React 组件发布
dispatch('button:clicked', { from: 'react' })

// Vue 组件订阅
on('button:clicked', (data) => {
  console.log('Received:', data)
})
1
2
3
4
5
6
7
8
9

适用:跨框架通信(React + Vue + Angular)、微前端。


7️⃣ 代理模式 (Proxy Store)

📁 ProxyStore/ | 📄 文档

核心文件

原理:ES6 Proxy 拦截读写操作,自动触发响应。

import { state, watch } from './ProxyStore/ProxyStoreSingleton'

// Vue3 风格监听
watch(
  () => state.count,
  (value) => console.log('Count:', value),
  { immediate: true }
)

// 直接赋值,自动触发订阅
state.count = 10 // 输出: Count: 10
state.count++ // 输出: Count: 11
1
2
3
4
5
6
7
8
9
10
11
12

风格:类似 Vue 3 响应式 / Valtio。


🪝 React Hook 建议

由于各模式的 API 设计不同(这是刻意的),更推荐在业务侧针对“你选择的那种模式”写一个非常薄的 Hook 适配层。


📚 扩展阅读

上次更新:
(adsbygoogle = window.adsbygoogle || []).push({});