微前端MFE:(React 與 Angular)框架之間的通信方式

????????在 微前端(MFE, Micro Frontends) 中使用 CustomEvent?是非常常見的,尤其是在不同子應用(Micro Apps)之間通信的時候。今天將以React 主應用 ? Angular 子應用 之間的通信進行示例


React 主應用 <-> Angular 子應用 用 mitt(事件總線) 通信示例


1. React 主應用

  • 通過 props 給 Angular 子應用傳遞數據和回調函數

  • 使用 mitt(事件總線)進行異步事件廣播

// React 主應用示例(App.jsx)import React, { useState, useEffect } from 'react';
import mitt from 'mitt';const eventBus = mitt();
window.eventBus = eventBus;function loadAngularApp(props) {// 假設 Angular 應用掛載到 #angular-container// 并且 Angular 子應用暴露了全局啟動函數 angularApp.mountwindow.angularApp.mount(document.getElementById('angular-container'), props);
}export default function App() {const [message, setMessage] = useState('');useEffect(() => {// 監聽來自子應用的消息eventBus.on('from-angular', (msg) => setMessage(msg));return () => eventBus.off('from-angular');}, []);const onNotifyFromReact = (msg) => {setMessage('React 接收到子應用消息:' + msg);};const propsForAngular = {user: { id: 1, name: 'ReactUser' },notifyParent: onNotifyFromReact,};useEffect(() => {loadAngularApp(propsForAngular);}, []);return (<div><h1>React 主應用</h1><p>消息:{message}</p><div id="angular-container" /><button onClick={() => eventBus.emit('from-react', 'React 主動發消息')}>React 向 Angular 發送消息</button></div>);
}

2. Angular 子應用

  • 暴露 mount 方法接收父應用傳來的 props

  • 通過傳入的回調 notifyParent 通知 React

  • 使用 window.eventBus 監聽 React 發來的事件

// Angular 子應用核心代碼(app.component.ts + bootstrap)import { Component, Input, OnDestroy } from '@angular/core';@Component({selector: 'app-root',template: `<h2>Angular 子應用</h2><p>接收的用戶:{{ user?.name }}</p><button (click)="notifyReact()">通知 React</button>`,
})
export class AppComponent implements OnDestroy {@Input() user: any;@Input() notifyParent!: (msg: string) => void;private onFromReact = (msg: string) => alert('Angular 收到 React 消息: ' + msg);ngOnInit() {window.eventBus.on('from-react', this.onFromReact);}notifyReact() {if (this.notifyParent) this.notifyParent('來自 Angular 的消息');}ngOnDestroy() {window.eventBus.off('from-react', this.onFromReact);}
}// 暴露給主應用掛載用的方法
export function mount(container: HTMLElement, props: any) {const moduleRef = platformBrowserDynamic().bootstrapModule(AppModule);// 這里需要將 props 注入到 Angular 應用,比如用 InjectionToken 或服務// 簡單示意:const appRef = moduleRef.injector.get(ApplicationRef);// 把 props 傳給 AppComponent,具體實現因項目不同略有差異// 也可以通過全局變量或服務傳遞container.appendChild(document.createElement('app-root'));// 實際渲染交給 Angular
}

3. 關鍵點總結

方式說明
propsReact 主應用傳給 Angular 子應用用戶數據和回調函數
回調函數Angular 調用回調函數通知 React 主應用
mitt 事件總線React 和 Angular 異步事件廣播,支持多對多通信
掛載函數Angular 通過暴露 mount(container, props) 給 React 調用

React 主應用 <-> Angular 子應用 用 CustomEvent 通信示例


? 在 MFE 中使用 CustomEvent 的意義:

微前端架構中,每個子應用通常是相互隔離獨立運行的。它們可能是由不同團隊使用不同技術棧開發的,因此需要一種輕量、技術無關的通信機制,而 CustomEvent 就是其中一種最佳選擇。


?? 典型用法:主應用和子應用之間通信

🔁 從子應用向主應用發送事件
// 子應用中
const loginSuccessEvent = new CustomEvent('user-login', {detail: { username: 'alice', token: 'abc123' }
});window.dispatchEvent(loginSuccessEvent);
🔄 主應用監聽這個事件
// 主應用中
window.addEventListener('user-login', (e) => {console.log('收到來自子應用的登錄事件:', e.detail);// 可以更新全局狀態、通知其他子應用等
});

📡 場景例子:

  • 用戶登錄事件廣播:一個子應用登錄成功,主應用收到后可同步狀態到其他子應用。

  • 路由通知:當子應用內部路由變化,通知主應用做高亮或記錄。

  • 數據共享:某子應用加載了某數據,廣播出去給其他依賴它的應用使用。


完整示例:

CustomEvent 實現 React 主應用和 Angular 子應用之間通信,核心思路就是:

  • 一方通過 window.dispatchEvent(new CustomEvent('事件名', { detail: 數據 })) 觸發事件

  • 另一方通過 window.addEventListener('事件名', callback) 監聽事件并拿到數據


1. React 主應用發送事件,接收 Angular 反饋
// React 主應用示例import React, { useEffect, useState } from 'react';export default function App() {const [message, setMessage] = useState('');useEffect(() => {// 監聽 Angular 發送的 CustomEventconst handler = (event) => {setMessage('收到 Angular 消息: ' + event.detail);};window.addEventListener('from-angular', handler);return () => {window.removeEventListener('from-angular', handler);};}, []);// 發送事件給 Angularconst sendMessageToAngular = () => {window.dispatchEvent(new CustomEvent('from-react', { detail: '你好,Angular!' }));};return (<div><h1>React 主應用</h1><button onClick={sendMessageToAngular}>發送消息給 Angular</button><p>{message}</p><div id="angular-container" /></div>);
}

2. Angular 子應用監聽 React 事件,發送反饋
// Angular 子應用核心代碼(app.component.ts)import { Component, OnInit, OnDestroy } from '@angular/core';@Component({selector: 'app-root',template: `<h2>Angular 子應用</h2><button (click)="sendMessageToReact()">發送消息給 React</button>`,
})
export class AppComponent implements OnInit, OnDestroy {private fromReactHandler = (event: CustomEvent) => {alert('Angular 收到 React 事件: ' + event.detail);};ngOnInit() {window.addEventListener('from-react', this.fromReactHandler as EventListener);}ngOnDestroy() {window.removeEventListener('from-react', this.fromReactHandler as EventListener);}sendMessageToReact() {window.dispatchEvent(new CustomEvent('from-angular', { detail: '你好,React!' }));}
}

3. Angular 應用掛載給 React 主應用調用(簡要示意)

注意下面有A方式B方式,可根據實際情況進行選擇使用

//A方式: angularApp/bootstrap.tsexport function mount(container: HTMLElement) {// 啟動 Angular 應用,把它渲染到 containerplatformBrowserDynamic().bootstrapModule(AppModule).then(() => {container.appendChild(document.createElement('app-root'));});
}//B方式
import { enableProdMode } from "@angular/core";
import { environment } from "./environments/environment";
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import "zone.js";
import { AppModule } from "./app/app.module";if (environment.production) {enableProdMode();
}let appRef: any = null;const mount = async () => {appRef = await platformBrowserDynamic().bootstrapModule(AppModule).catch(err => console.error(err));
};const unmount = () => {if (appRef) {appRef.destroy();appRef = null;}
};export { mount, unmount };

React 主應用調用時傳入容器:

//A方式
window.angularApp.mount(document.getElementById('angular-container'));//B方式const [AngularComponent, setAngularComponent] = useState(null);let unmountFunction = null;useEffect(() => {const loadModule = async () => {const { mount, unmount } = await loadRemoteModule({ type: 'module',  remoteEntry: 'http://localhost:4200/remoteEntry.js',remoteName: 'B方式',exposedModule: './ReactMfeModule'});unmountFunction = unmount;setTimeout(() => {setAngularComponent(mount);setTimeout(() => {dispatchReactHostAppData();//傳遞初始數據使用}, 1000)}, 200);};loadModule();return () => {if (unmountFunction) {unmountFunction();}};}, []);

總結

優點注意事項
1. 無需共享庫,框架無關1. 事件名要唯一,防止沖突
2. 傳遞數據簡單、靈活2. 事件數據建議放在 detail 字段
3. 瀏覽器原生,性能不錯3. 調試時注意事件監聽和解綁
4. 適合松耦合異步通信

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/910175.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/910175.shtml
英文地址,請注明出處:http://en.pswp.cn/news/910175.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

408考研逐題詳解:2010年第1題——理解棧的基本操作

2010年第1題 若元素 a&#xff0c;b&#xff0c;c&#xff0c;d&#xff0c;e&#xff0c;f 依次進棧&#xff0c;允許進棧、退棧操作交替進行&#xff0c;但不允許連續三次進行退棧操作&#xff0c;則不可能得到的出棧序列是&#xff08; &#xff09; A. dcebfa \qquad B.…

python追加合并excel效率記錄

第一種合并方法&#xff1a; 在sheet的第一行&#xff0c;追加新表concat舊表 read_excel讀取舊表全部 to_excel新表追加寫入舊表 需要的時間&#xff1a; 第二種合并方法&#xff1a; 在sheet的最后一行&#xff0c;直接追加新表 load_book只讀用來獲取舊表sheet行數 read_ex…

公鑰加密與簽名算法計算詳解(含計算題例子)

一、RSA 加密算法 密鑰生成&#xff1a; 選兩個大素數 p 和 q計算 n p q計算 φ(n) (p-1)(q-1)選整數 e 滿足 1 < e < φ(n) 且 gcd(e, φ(n)) 1計算 d 滿足 d e ≡ 1 mod φ(n) 公鑰&#xff1a;(e, n) 私鑰&#xff1a;(d, n) 加密&#xff1a; c ≡ m? mod…

63 網絡交互的過程中目標設備的選擇

前言 這里主要是 調研一下 發送網絡數據包的過程中 選擇網絡設備 比如 向本機發送信息, 走的是 lo 向局域網其他主機發送信息, 走無線網卡 或者 有線網卡 基于 linux 的調試 這里主要是基于 ping 192.168.1.2 的調試 skb->dev 的初始化是在 skb->_skb_refdst 初…

DE2-115板子上用 Verilog編程實現一個分秒計數器

一、實驗目的 掌握 Verilog 語言在硬件描述中的應用&#xff0c;通過編程實現分秒計數器的邏輯功能。 學習并實踐按鍵消抖的原理與實現方法&#xff0c;提升對硬件電路中信號處理的理解。 熟悉在 DE2-115 開發板上進行 Verilog 程序的開發、調試及下載驗證流程&#xff0c;將…

R4 LSTM-火災溫度預測

import tensorflow as tf import pandas as pd import numpy as npgpus tf.config.list_physical_devices("GPU") if gpus:tf.config.experimental.set_memory_growth(gpus[0], True) #設置GPU顯存用量按需使用tf.config.set_visible_devices([gpus[0]],&…

什么是跨域問題?后端如何解決跨域問題?

跨域問題是指瀏覽器為了安全&#xff0c;對不同域&#xff08;包含不同協議、不同端口或不同主機名&#xff09;的請求進行限制&#xff0c;從而導致請求無法正常訪問后端接口。 跨域問題的產生源于瀏覽器的同源策略&#xff08;Same-Origin Policy&#xff09;&#xff0c;這…

vue | rollup 打包 | 配置 rollup.config.js 文件,更改 rollup的行為

原因&#xff1a;將入口文件 轉為 esm 和 umd 兩種格式&#xff0c;要配置 rollup Rollup 已內置到 vite 工具中&#xff0c; 命令行打包&#xff0c;參數多&#xff0c;麻煩——》解決&#xff1a;創建配置文件&#xff0c;js 寫的&#xff0c;rollup.config.js 配置 rollup.…

服務器中物理處理器和邏輯處理器的區別?

在服務器或任何計算機系統中&#xff0c;**物理處理器&#xff08;Physical Processor&#xff09;和邏輯處理器&#xff08;Logical Processor&#xff09;**是兩個不同的概念&#xff0c;它們分別代表了硬件層面和操作系統層面的處理能力。 物理處理器&#xff08;Physical P…

【Gin框架】中間件

1. 什么是中間件 (Middleware)&#xff1f; 在 Web 框架的語境下&#xff0c;中間件 (Middleware) 是一種可重用的軟件組件或函數&#xff0c;它被設計用來在 HTTP 請求-響應生命周期中的特定點攔截和處理請求或響應。在 Gin 框架中&#xff0c;中間件特指符合 gin.HandlerFun…

STUN (Session Traversal Utilities for NAT) 服務器是一種網絡協議

STUN (Session Traversal Utilities for NAT) 服務器是一種網絡協議&#xff0c;主要用于幫助位于網絡地址轉換 (NAT) 設備&#xff08;如路由器&#xff09;后面的客戶端發現自己的公共 IP 地址和端口號。這對于建立點對點 (P2P) 通信至關重要&#xff0c;尤其是在 VoIP&#…

AQS詳解

概念 AQS&#xff08;AbstractQueuedSynchronizer&#xff09; 是并發包&#xff08;java.util.concurrent&#xff09;的核心組件&#xff0c;用于構建鎖和同步器&#xff08;如 ReentrantLock、Semaphore、CountDownLatch 等&#xff09;。它通過維護一個 CLH 隊列 和 同步狀…

python實戰項目76:51job數據采集與分析

python實戰項目76:51job數據采集與分析 一、數據采集二、數據預處理2.1 導入相關庫、讀取數據2.2 查看數據2.3 處理數據、刪除重復值、刪除空值2.4 處理薪資水平字段數據三、數據可視化3.1 不同公司規模招聘崗位數量分布3.2 不同公司性質招聘崗位數量分布3.3 不同年限要求招聘崗…

每天一個前端小知識 Day 7 - 現代前端工程化與構建工具體系

現代前端工程化與構建工具體系 1. 為什么要工程化&#xff1f;&#xff08;面試高頻問題&#xff09; 問題痛點&#xff1a; 模塊太多、無法組織&#xff1b;代碼冗長、性能差&#xff1b;瀏覽器兼容性差&#xff1b;團隊協作混亂&#xff0c;缺少規范與自動化。 工程化目標…

shell腳本--變量及特殊變量,算術邏輯運算

1.變量是什么 2.變量類型 3.動態&#xff0c;靜態&#xff0c;強弱類型 4.變量的命名 5.變量的定義和引用 5.1三種變量類型 普通變量 環境變量 局部變量 5.2單引號&#xff0c;雙引號&#xff0c;強弱引用 雙引號對變量賦值的影響01:59&#xff1a;給變量加雙引號&#x…

Python粒子群優化算法結合熱力圖TIFF文件案例

Python粒子群優化算法結合熱力圖TIFF文件案例 1. 項目概述 本項目使用粒子群優化算法(PSO)在熱力圖TIFF文件中尋找溫度最高點。熱力圖通常以地理空間數據形式存儲(TIFF格式),包含溫度分布信息。PSO算法模擬鳥群覓食行為,通過粒子協作在搜索空間中尋找最優解。 import …

使用Mambaout替換YOLObackbone 整合全局信息,提升遮擋目標檢測中定位能力,以及小目標、多尺度

近年來&#xff0c;Transformer 架構雖在各類任務中成為主流&#xff0c;但注意力機制的二次復雜度對長序列處理構成挑戰。為此&#xff0c;類似 RNN 的模型如 Mamba 被引入&#xff0c;其核心是狀態空間模型&#xff08;SSM&#xff09;&#xff0c;旨在以線性復雜度處理長序列…

力扣網C語言編程題:接雨水(動態規劃實現)

一. 簡介 本文記錄力扣網上的邏輯編程題&#xff0c;涉及數組方面的&#xff0c;這里記錄一下 C語言實現和Python實現。 二. 力扣網C語言編程題&#xff1a;接雨水 題目&#xff1a;接雨水 給定 n 個非負整數表示每個寬度為 1 的柱子的高度圖&#xff0c;計算按此排列的柱子…

關于ubuntu環境下vscode進行debug的隨筆

CMakeLists.txt的編寫 頂層目錄的CMakelists.txt 目錄&#xff1a;./CMakeLists.txt #./CMakeLists.txt cmake_minimum_required(VERSION 3.10) project(xxx_project_name LANGUAGES CXX) #設置工程名# 設置 C 標準和編譯選項 set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_ST…

技術演進中的開發沉思-9:window編程系列-內核對象線程同步(下)

今天我們繼續走進 Windows 內核的世界&#xff0c;就昨天沒說完的內核對象與線程同步內容接著繼續&#xff0c;它們就像精密儀器里的齒輪&#xff0c;雖不顯眼&#xff0c;卻至關重要。 異步設備 I/O 在 Windows 系統中&#xff0c;異步設備 I/O 就像是一場精心編排的接力賽。…