鍏堟潵寮犲浘鐗囧帇鍘嬫儕
image.png
鍦ㄧ嚎demo锛?a href="https://links.jianshu.com/go?to=http%3A%2F%2Fwzs.bengdada.com%2F" target="_blank">wzs.bengdada.com/
鍗曠嫭璁块棶鍦ㄧ嚎瀛愬簲鐢細
- subapp/micro-react
- subapp/micro-vue2
- subapp/micro-vue3
涓€.瀵艰
1.浠€涔堟槸寰墠绔?/h5>
- 寰墠绔槸涓€绉嶅涓洟闃熼€氳繃鐙珛鍙戝竷鍔熻兘鐨勬柟寮忔潵鍏卞悓鏋勫缓鐜颁唬鍖?web 搴旂敤鐨勬妧鏈墜娈靛強鏂规硶绛栫暐銆?/li>
- 寰墠绔灦鏋勫叿澶囦互涓嬪嚑涓牳蹇冧环鍊硷細
鎶€鏈爤鏃犲叧
: 涓绘鏋朵笉闄愬埗鎺ュ叆搴旂敤鐨勬妧鏈爤锛屽井搴旂敤鍏峰瀹屽叏鑷富鏉?br>
鐙珛寮€鍙戙€佺嫭绔嬮儴缃?/code> : 寰簲鐢ㄤ粨搴撶嫭绔嬶紝鍓嶅悗绔彲鐙珛寮€鍙戯紝閮ㄧ讲瀹屾垚鍚庝富妗嗘灦鑷姩瀹屾垚鍚屾鏇存柊
澧為噺鍗囩骇
:鍦ㄩ潰瀵瑰悇绉嶅鏉傚満鏅椂锛屾垜浠€氬父寰堥毦瀵逛竴涓凡缁忓瓨鍦ㄧ殑绯荤粺鍋氬叏閲忕殑鎶€鏈爤鍗囩骇鎴栭噸鏋勶紝鑰屽井鍓嶇鏄竴绉嶉潪甯稿ソ鐨勫疄鏂芥笎杩涘紡閲嶆瀯鐨勬墜娈靛拰绛栫暐
鐙珛杩愯鏃?/code> : 姣忎釜寰簲鐢ㄤ箣闂寸姸鎬侀殧绂伙紝杩愯鏃剁姸鎬佷笉鍏变韩
- 寰墠绔灦鏋勬棬鍦ㄨВ鍐冲崟浣撳簲鐢ㄥ湪涓€涓浉瀵归暱鐨勬椂闂磋法搴︿笅锛岀敱浜庡弬涓庣殑浜哄憳銆佸洟闃熺殑澧炲銆佸彉杩侊紝浠庝竴涓櫘閫氬簲鐢ㄦ紨鍙樻垚涓€涓法鐭冲簲鐢?Frontend Monolith)鍚庯紝闅忎箣鑰屾潵鐨勫簲鐢ㄤ笉鍙淮鎶ょ殑闂銆傝繖绫婚棶棰樺湪浼佷笟绾?Web 搴旂敤涓挨鍏跺父瑙併€?/li>
2.qiankun鏄粈涔?/h5>
- qiankun 鏄竴涓熀浜?single-spa 鐨?a href="https://links.jianshu.com/go?to=https%3A%2F%2Fmicro-frontends.org%2F" target="_blank">寰墠绔?/a>瀹炵幇搴擄紝鏃ㄥ湪甯姪澶у鑳芥洿绠€鍗曘€佹棤鐥涚殑鏋勫缓涓€涓敓浜у彲鐢ㄥ井鍓嶇鏋舵瀯绯荤粺銆?br>
瀹樼綉: https://qiankun.umijs.org/zh
- qiankun鐗规€?br>
鍩轰簬 single-spa 灏佽锛屾彁渚涗簡鏇村姞寮€绠卞嵆鐢ㄧ殑 API銆?br>
鎶€鏈爤鏃犲叧锛屼换鎰忔妧鏈爤鐨勫簲鐢ㄥ潎鍙?浣跨敤/鎺ュ叆锛屼笉璁烘槸 React/Vue/Angular/JQuery 杩樻槸鍏朵粬绛夋鏋躲€?br>
HTML Entry 鎺ュ叆鏂瑰紡锛岃浣犳帴鍏ュ井搴旂敤鍍忎娇鐢?iframe 涓€鏍风畝鍗曘€?br>
鏍峰紡闅旂锛岀‘淇濆井搴旂敤涔嬮棿鏍峰紡浜掔浉涓嶅共鎵般€?br>
JS 娌欑锛岀‘淇濆井搴旂敤涔嬮棿 鍏ㄥ眬鍙橀噺/浜嬩欢 涓嶅啿绐併€?br>
鈿★笍 璧勬簮棰勫姞杞?/strong>锛屽湪娴忚鍣ㄧ┖闂叉椂闂撮鍔犺浇鏈墦寮€鐨勫井搴旂敤璧勬簮锛屽姞閫熷井搴旂敤鎵撳紑閫熷害銆?br>
umi 鎻掍欢锛屾彁渚涗簡 @umijs/plugin-qiankun 渚?umi 搴旂敤涓€閿垏鎹㈡垚寰墠绔灦鏋勭郴缁熴€?/li>
- 浜嗚В瀹岀悊璁哄熀纭€锛岃鎴戜滑鍔ㄦ墜瀹炶返涓€涓嬄仿仿?/li>
浜?寤虹珛椤圭洰
鎶€鏈爤鏃犲叧
: 涓绘鏋朵笉闄愬埗鎺ュ叆搴旂敤鐨勬妧鏈爤锛屽井搴旂敤鍏峰瀹屽叏鑷富鏉?br>
鐙珛寮€鍙戙€佺嫭绔嬮儴缃?/code> : 寰簲鐢ㄤ粨搴撶嫭绔嬶紝鍓嶅悗绔彲鐙珛寮€鍙戯紝閮ㄧ讲瀹屾垚鍚庝富妗嗘灦鑷姩瀹屾垚鍚屾鏇存柊
澧為噺鍗囩骇
:鍦ㄩ潰瀵瑰悇绉嶅鏉傚満鏅椂锛屾垜浠€氬父寰堥毦瀵逛竴涓凡缁忓瓨鍦ㄧ殑绯荤粺鍋氬叏閲忕殑鎶€鏈爤鍗囩骇鎴栭噸鏋勶紝鑰屽井鍓嶇鏄竴绉嶉潪甯稿ソ鐨勫疄鏂芥笎杩涘紡閲嶆瀯鐨勬墜娈靛拰绛栫暐
鐙珛杩愯鏃?/code> : 姣忎釜寰簲鐢ㄤ箣闂寸姸鎬侀殧绂伙紝杩愯鏃剁姸鎬佷笉鍏变韩
- qiankun 鏄竴涓熀浜?single-spa 鐨?a href="https://links.jianshu.com/go?to=https%3A%2F%2Fmicro-frontends.org%2F" target="_blank">寰墠绔?/a>瀹炵幇搴擄紝鏃ㄥ湪甯姪澶у鑳芥洿绠€鍗曘€佹棤鐥涚殑鏋勫缓涓€涓敓浜у彲鐢ㄥ井鍓嶇鏋舵瀯绯荤粺銆?br> 瀹樼綉: https://qiankun.umijs.org/zh
- qiankun鐗规€?br>
鍩轰簬 single-spa 灏佽锛屾彁渚涗簡鏇村姞寮€绠卞嵆鐢ㄧ殑 API銆?br>
鎶€鏈爤鏃犲叧锛屼换鎰忔妧鏈爤鐨勫簲鐢ㄥ潎鍙?浣跨敤/鎺ュ叆锛屼笉璁烘槸 React/Vue/Angular/JQuery 杩樻槸鍏朵粬绛夋鏋躲€?br>
HTML Entry 鎺ュ叆鏂瑰紡锛岃浣犳帴鍏ュ井搴旂敤鍍忎娇鐢?iframe 涓€鏍风畝鍗曘€?br>
鏍峰紡闅旂锛岀‘淇濆井搴旂敤涔嬮棿鏍峰紡浜掔浉涓嶅共鎵般€?br>
JS 娌欑锛岀‘淇濆井搴旂敤涔嬮棿 鍏ㄥ眬鍙橀噺/浜嬩欢 涓嶅啿绐併€?br>
鈿★笍 璧勬簮棰勫姞杞?/strong>锛屽湪娴忚鍣ㄧ┖闂叉椂闂撮鍔犺浇鏈墦寮€鐨勫井搴旂敤璧勬簮锛屽姞閫熷井搴旂敤鎵撳紑閫熷害銆?br>
umi 鎻掍欢锛屾彁渚涗簡 @umijs/plugin-qiankun 渚?umi 搴旂敤涓€閿垏鎹㈡垚寰墠绔灦鏋勭郴缁熴€?/li>
- 浜嗚В瀹岀悊璁哄熀纭€锛岃鎴戜滑鍔ㄦ墜瀹炶返涓€涓嬄仿仿?/li>
浜?寤虹珛椤圭洰
image.png
濡傚浘: 鎴戝缓绔嬩簡涓€涓富搴旂敤鍜屼笁涓瓙搴旂敤
涓诲簲鐢? main vue3鎼缓
"vue": "^3.0.0",
瀛愬簲鐢? micro-react react18鎼缓
"react": "^18.1.0",
瀛愬簲鐢? micro-vue2 vue2鎼缓
"vue": "^2.6.11",
瀛愬簲鐢? micro-vue3 vue3鎼缓
"vue": "^3.0.0",
娉ㄦ剰 :
vue3鎶€鏈€夊瀷鎴戜娇鐢ㄧ殑鏄痸ue3 + webpack 锛寁ite鐩墠瀵逛簬qiankun杩樹笉鏄お鍙嬪ソ 锛岀‖瑕佹悶vite浠d环浼氬緢澶э紝鍚庣画绛夊畼缃戜紭鍖栧悗鎴戜滑鍦ㄥ幓浣跨敤vite
鐢变簬鎼缓椤圭洰澶畝鍗曟垜灏变笉璇存槑浜?~ ovo
涓?涓诲簲鐢?/h1>
娉ㄦ剰:
qiankun 闇€瑕佷竴涓富搴旂敤 鏉ユ敞鍏ユ墍鏈夌殑瀛愬簲鐢?br>
鍏堝畨瑁呬咕鍧ょ殑渚濊禆鍖?/p>
yarn add qiankun # 鎴栬€?npm i qiankun -S
鐩墠涔惧潳鏄?.0鐗堟湰 瀹夎鍚巔ackage.json 鏄?.72鐗堟湰
image.png
鍦ㄥ畨瑁?element-plus 鎶婇」鐩殑甯冨眬绠€鍗曞仛涓€涓?/p>
npm install element-plus --save
娉ㄦ剰:
vue3 瀹夎element-plus锛?vue2瀹夎element-ui
src涓嬫柊寤簃icro-app.js 鐢ㄤ簬瀛樻斁鎵€鏈夊瓙搴旂敤
const microApps = [
{
name: 'micro-react', //搴旂敤鍚?椤圭洰鍚嶆渶濂戒篃鏄繖涓? entry: '//localhost:20000', //榛樿浼氬姞杞借繖涓猦tml 瑙f瀽閲岄潰鐨刯s 鍔ㄦ€佺殑鎵ц 锛堝瓙搴旂敤蹇呴』鏀寔璺ㄥ煙锛夊唴閮ㄧ敤鐨刦etch
activeRule: '/react', // 婵€娲荤殑璺緞
container: '#micro-react', // 瀹瑰櫒鍚? props: {}, //鐖跺瓙搴旂敤閫氫俊
},
{
name: 'micro-vue2',
entry: '//localhost:30000',
activeRule: '/vue2',
container: '#micro-vue2',
props: {},
},
{
name: 'micro-vue3',
entry: '//localhost:40000',
activeRule: '/vue3',
container: '#micro-vue3',
props: {},
},
];
export default microApps;
鏂板缓vue.config.js
module.exports = {
devServer: {
port: 8000,
headers: {
// 閲嶇偣1: 鍏佽璺ㄥ煙璁块棶瀛愬簲鐢ㄩ〉闈? 'Access-Control-Allow-Origin': '*',
},
},
};
Main椤甸潰
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
// createApp(App).use(store).use(router).mount('#app')
//-----------------------涓婇潰鏄師鍏堢殑,涓嬮潰鏄柊澧炵殑-----------------------------
import ElementPlus from 'element-plus'; //element-plus
import 'element-plus/dist/index.css'; //element-plus
import { registerMicroApps, start } from 'qiankun';
import microApps from './micro-app';
let app = createApp(App);
app.use(store);
app.use(router);
app.use(ElementPlus);
app.mount('#app');
registerMicroApps(microApps, {
//杩樻湁涓€浜涚敓鍛藉懆鏈?濡傛灉闇€瑕佸彲浠ユ牴鎹畼缃戞枃妗f寜闇€鍔犲叆
beforeMount(app) {
console.log('鎸傝浇鍓?, app);
},
afterMount(app) {
console.log('鍗歌浇鍚?, app);
},
});
start({
prefetch: false, //鍙栨秷棰勫姞杞? sandbox: { experimentalStyleIsolation: true }, //娌欑洅妯″紡
});
杩涘叆App椤甸潰绠€鍗曡皟涓嬪竷灞€
<template>
<el-menu :router="true" mode="horizontal">
<!-- 瀛愬簲鐢ㄧ殑璺宠浆璺緞 -->
<el-menu-item index="/">涓诲簲鐢?main</el-menu-item>
<el-menu-item index="/react">瀛愬簲鐢?react18</el-menu-item>
<el-menu-item index="/vue2">瀛愬簲鐢?vue2</el-menu-item>
<el-menu-item index="/vue3">瀛愬簲鐢?vue3</el-menu-item>
<el-menu-item index="/about">{{ $store.state.GlobalData }}</el-menu-item>
</el-menu>
<router-view />
<!-- 瀛愬簲鐢ㄧ殑瀹瑰櫒 -->
<div id="micro-react"></div>
<div id="micro-vue2"></div>
<div id="micro-vue3"></div>
</template>
<script>
export default {
name: 'App',
setup() {
return {};
},
};
</script>
<style lang="less">
html,
body,
#app {
width: 100%;
height: 100%;
margin: 0;
}
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
}
</style>
闇€瑕佹敞鎰?/code>: app閲岀殑瀹瑰櫒鍚嶅拰璺宠浆璺緞閮戒笉鏄殢渚胯捣鐨?闇€瑕佸拰micro-app.js 瀹氫箟濂界殑瀛愬簲鐢ㄤ竴涓€瀵瑰簲
image.png
鍒版涓诲簲鐢ㄦ惌寤哄畬姣晘~~ovo
鍥?瀛愬簲鐢?/h1>
1.react
瀹夎npm install react-app-rewired 閲嶅啓榛樿鐨剅eact閰嶇疆鏂囦欢
npm install react-app-rewired --save
淇敼package.json,鍘熸湰鐨剅eact-script 鏀逛负react-app-rewired
"scripts": {
"start": "react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test",
"eject": "react-app-rewired eject"
},
瀹夎npm i react-router-dom 鎴戝畨瑁呯殑鏄渶鏂扮増鏈?"react-router-dom": "^6.3.0"
npm i react-router-dom --save
鏍圭洰褰曚笅鏂板缓.env鏂囦欢
PORT=20000
# 闃叉鐑洿鏂板嚭閿?WDS_SOCKET_PORT=20000
src涓嬫柊寤簆ublic-path.js (鐢ㄤ簬淇敼杩愯鏃剁殑 publicPath)
//鍒ゆ柇鏄惁鏄痲iankun鍔犺浇
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
src涓嬫柊寤?config-overrides.js
const { name } = require('./package');
module.exports = {
webpack: config => {
config.output.library = `${name}-[name]`;
config.output.libraryTarget = 'umd';
config.output.globalObject = 'window';
return config;
},
devServer: _ => {
const config = _;
config.headers = {
'Access-Control-Allow-Origin': '*',
};
config.historyApiFallback = true;
config.hot = false;
config.watchContentbase = false;
config.liveReload = false;
return config;
},
};
杩涘叆src涓媔ndex.js
// import logo from './logo.svg';
// import './App.css';
// function App() {
// return (
// <div className="App">
// <header className="App-header">
// <img src={logo} className="App-logo" alt="logo" />
// <p>
// Edit <code>src/App.js</code> and save to reload.
// </p>
// <a
// className="App-link"
// href="https://reactjs.org"
// target="_blank"
// rel="noopener noreferrer"
// >
// Learn React
// </a>
// </header>
// </div>
// );
// }
// export default App;
// ------------------------涓婇潰鍘熷厛鐨勶紝涓嬮潰鏈€鏂扮殑------------------------------------
import logo from './logo.svg';
import './App.css';
import { BrowserRouter as Router, Routes, Route, link } from 'react-router-dom';
function App() {
return (
<>
{}
<link to="/">棣栭〉</link>
<link to="/about">鍏充簬椤甸潰</link>
<Routes>
<Route path="/" element={<Home />}></Route>
<Route path="/about" element={<about />}></Route>
</Routes>
</Router>
</>
);
}
function about() {
return <div>about</div>;
}
function Home() {
return (
<div>
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a className="App-link" href="https://reactjs.org" target="_blank" rel="noopener noreferrer">
Learn React
</a>
</header>
</div>
);
}
export default App;
2.vue2
src涓嬫柊寤簆ublic-path.js 鐢ㄤ簬淇敼杩愯鏃剁殑 publicPath
// eslint-disable-next-line no-undef
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
鍦╩ain椤甸潰 寮曞叆public-path.js鏂囦欢
// import Vue from 'vue';
// import App from './App.vue';
// import router from './router';
// Vue.config.productionTip = false
// new Vue({
// router,
// render: h => h(App)
// }).$mount('#app')
// 路路路路路路路路路路路路路路路路路涓婇潰鍘熷厛鐨?涓嬮潰鏂板鐨劼仿仿仿仿仿仿仿仿仿仿仿仿仿仿仿仿仿仿仿仿?import './public-path';
import Vue from 'vue';
import App from './App.vue';
import router from './router';
// Vue.config.productionTip = false
let instance = null;
function render(props = {}) {
const { container } = props;
instance = new Vue({
router,
render: (h) => h(App),
}).$mount(container ? container.querySelector('#app') : '#app');
}
// 濡備綍鐙珛杩愯寰簲鐢紵
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
export async function bootstrap(props) {
// 鍚姩
}
export async function mount(props) {
// 鎸傝浇 onGlobalStateChange 鍙€氳繃杩欎釜灞炴€ф潵杩涜鐖跺瓙搴旂敤閫氫俊 鍙戝竷璁㈤槄鏈哄埗
render(props);
}
export async function unmount(props) {
// 鍗歌浇
instance.$destroy();
}
鏂板vue.config.js鏂囦欢
const { name } = require('./package');
module.exports = {
devServer: {
port: 30000,
headers: {
'Access-Control-Allow-Origin': '*', //寮€鍙戞椂澧炲姞璺ㄥ煙 琛ㄧず鎵€鏈変汉閮藉彲浠ヨ闂垜鐨勬湇鍔″櫒
},
},
configureWebpack: {
output: {
library: `${name}-[name]`,
libraryTarget: 'umd', // 鎶婂瓙搴旂敤鎵撳寘鎴?umd 搴撴牸寮? jsonpFunction: `webpackJsonp_${name}`,
},
},
};
router.js鏂囦欢
const router = new VueRouter({
mode: 'history',
// base: process.env.base_URL,
base: '/vue2',
routes,
});
3.vue3
src涓嬫柊寤簆ublic-path.js 鐢ㄤ簬淇敼杩愯鏃剁殑 publicPath
// eslint-disable-next-line no-undef
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
鍦╩ain椤甸潰 寮曞叆public-path.js鏂囦欢
import './public-path'; // 娉ㄦ剰闇€瑕佸紩鍏ublic-path
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
let instance = null;
function render({ container } = {}) {
instance = createApp(App);
instance.use(router);
instance.use(store);
instance.mount(container ? container.querySelector('#app') : '#app');
}
// 濡備綍鐙珛杩愯寰簲鐢紵
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
export async function bootstrap(props) {
// 鍚姩
}
export async function mount(props) {
// 鎸傝浇
render(props);
}
export async function unmount(props) {
// 鍗歌浇
instance.unmount();
instance = null;
}
鏂板vue.config.js鏂囦欢
const { name } = require('./package');
module.exports = {
devServer: {
port: 40000,
headers: {
'Access-Control-Allow-Origin': '*', //寮€鍙戞椂澧炲姞璺ㄥ煙 琛ㄧず鎵€鏈変汉閮藉彲浠ヨ闂垜鐨勬湇鍔″櫒
},
},
configureWebpack: {
output: {
library: `${name}-[name]`,
libraryTarget: 'umd', // 鎶婂瓙搴旂敤鎵撳寘鎴?umd 搴撴牸寮? jsonpFunction: `webpackJsonp_${name}`,
},
},
};
鍒拌繖閲岄」鐩惌寤哄畬姣曪紝鍩虹璺宠浆娌℃湁闂 锛屽彲浠ュ湪涓诲簲鐢ㄥ拰瀛愬簲鐢ㄨ烦杞?br>
bug
锛氫富搴旂敤鍜屽瓙搴旂敤浣跨敤涓嶅悓鐗堟湰鐨剉ue鍚庤矾鐢卞垏鎹㈡姤閿??
bug
锛氫富搴旂敤鏍峰紡涓庡瓙搴旂敤鏍峰紡鍐茬獊 ?
闇€姹?/code> 锛氱埗瀛愮粍浠朵紶鍙傚浣曞疄鐜??
闇€姹?/code> 锛氬浣曢儴缃??
鍒媴蹇?涓嬮潰鎴戜竴涓€瑙g瓟
5.bug
[Bug]涓诲簲鐢ㄥ拰瀛愬簲鐢ㄤ娇鐢ㄤ笉鍚岀増鏈殑vue鍚庤矾鐢卞垏鎹㈡姤閿?/h5>
闂鐨勫師鍥?/code> : vue-router 3.x涓巚ue-router 4.x璁剧疆鐨刪istory.state鐨勬暟鎹粨鏋勪笉鍚?br>
浣庣増鏈殑 vue-router 鍦?pushState 鐨勬椂鍊欙紝浼氳鐩栦涪澶变富璺敱鐨?history.state锛屽鑷翠富璺敱璺宠浆寮傚父
瑙e喅鍔炴硶
: 涓诲簲鐢ㄧ洃鍚瑀outer.beforEach 鎵嬪姩淇敼history.state鏁版嵁缁撴瀯
import _ from "lodash"
router.beforeEach((to, from, next) => {
if (_.isEmpty(history.state.current)) {
_.assign(history.state, { current: from.fullPath });
}
next();
});
[Bug]涓诲簲鐢ㄦ牱寮忎笌瀛愬簲鐢ㄦ牱寮忓啿绐?/h5>
鍙互閫氳繃缁檆ss鏍峰紡鍚嶅姞鍓嶇紑鏉ュ疄鐜伴殧绂?br>
https://blog.csdn.net/zjscy666/article/details/107864891
https://blog.csdn.net/m0_54854484/article/details/123442168
6.闇€姹?/h1>
[闇€姹俔 鐖跺瓙缁勪欢浼犲弬濡備綍瀹炵幇
qiankun
閫氳繃initGlobalState, onGlobalStateChange, setGlobalState瀹炵幇涓诲簲鐢ㄧ殑鍏ㄥ眬鐘舵€佺鐞嗭紝鐒跺悗榛樿浼氶€氳繃props
灏嗛€氫俊鏂规硶浼犻€掔粰瀛愬簲鐢ㄣ€傚厛鐪嬩笅瀹樻柟鐨勭ず渚嬬敤娉曪細
涓诲簲鐢?/strong>
// main/src/main.js
import { initGlobalState } from 'qiankun';
// 鍒濆鍖?state
const initialState = {
user: {} // 鐢ㄦ埛淇℃伅
};
const actions = initGlobalState(initialState);
actions.onGlobalStateChange((state, prev) => {
// state: 鍙樻洿鍚庣殑鐘舵€? prev 鍙樻洿鍓嶇殑鐘舵€? console.log(state, prev);
});
actions.setGlobalState(state);
actions.offGlobalStateChange();
瀛愬簲鐢?/strong>
// 浠庣敓鍛藉懆鏈?mount 涓幏鍙栭€氫俊鏂规硶锛宲rops榛樿浼氭湁onGlobalStateChange鍜宻etGlobalState涓や釜api
export function mount(props) {
props.onGlobalStateChange((state, prev) => {
// state: 鍙樻洿鍚庣殑鐘舵€? prev 鍙樻洿鍓嶇殑鐘舵€? console.log(state, prev);
});
props.setGlobalState(state);
}
杩欎袱娈典唬鐮佷笉闅剧悊瑙o紝鐖跺瓙搴旂敤閫氳繃onGlobalStateChange杩欎釜鏂规硶杩涜閫氫俊锛岃繖鍏跺疄鏄竴涓彂甯?璁㈤槄鐨勮璁℃ā寮忋€?br> ok锛屽畼鏂圭殑绀轰緥鐢ㄦ硶寰堢畝鍗曚篃瀹屽叏澶熺敤锛岀函Javascript鐨勮娉曪紝涓嶆秹鍙婁换浣曠殑vue鎴杛eact鐨勪笢瑗匡紝寮€鍙戣€呭彲鑷敱瀹氬埗銆?/p>
濡傛灉鎴戜滑鐩存帴浣跨敤瀹樻柟鐨勮繖涓ず渚嬶紝閭d箞鏁版嵁浼氭瘮杈冩澗鏁d笖璋冪敤澶嶆潅锛屾墍鏈夊瓙搴旂敤閮藉緱澹版槑onGlobalStateChange瀵圭姸鎬佽繘琛岀洃鍚紝鍐嶉€氳繃setGlobalState杩涜鏇存柊鏁版嵁銆?/p>
鍥犳锛屾垜浠緢鏈夊繀瑕佸鏁版嵁鐘舵€佸仛杩涗竴姝ョ殑灏佽璁捐
涓诲簲鐢╯rc涓嬫柊寤篴ctions.js
//src/actions.js
// 鐖跺瓙搴旂敤閫氫俊
import { initGlobalState } from 'qiankun';
import store from './store';
const state = {
//杩欓噷鍐欏垵濮嬪寲鏁版嵁
name: 'wang',
age: 123,
count: 0,
};
const actions = initGlobalState(state);
actions.onGlobalStateChange((state, prev) => {
console.log('涓诲簲鐢ㄥ彉鏇村墠锛?, state);
console.log('涓诲簲鐢ㄥ彉鏇村悗锛?, prev);
store.commit('setGlobalData', state);
});
store.commit('setGlobalData', state);
export default actions;
灏嗗垵濮嬪寲鐨勬暟鎹瓨鍒皏uex涓?濡傛灉鏁版嵁鍙樻洿浜?鍦ㄥ皢鍙樻洿鍚庣殑鏁版嵁瀛樺埌vuex
涓诲簲鐢╩ain store鏂囦欢澶逛笅index.js涓?/h5>
//store/index.js
import { createStore } from 'vuex';
export default createStore({
state: {
Globaldata: {},
},
mutations: {
setGlobalData(state, value) {
state.GlobalData = value;
},
},
actions: {},
modules: {},
});
鏈€鍚庡湪main.js 涓鍏?/p>
//main.js
import './actions.js'
瀛愬簲鐢?(vue3)
鏍稿績
:閫氳繃灏嗕富搴旂敤鐨刼nGlobalStateChange锛宻etGlobalState鏂规硶鎸傝浇鍒板叏灞€灏卞彲浠ヤ娇鐢ㄤ簡
import './public-path'; // 娉ㄦ剰闇€瑕佸紩鍏ublic-path
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
let instance = null;
//鏍稿績
function render(props) {
const { container, onGlobalStateChange, setGlobalState } = props;
console.log(props);
instance = createApp(App);
instance.config.globalProperties.$onGlobalStateChange = onGlobalStateChange;
instance.config.globalProperties.$setGlobalState = setGlobalState;
instance.use(router);
instance.use(store);
instance.mount(container ? container.querySelector('#app') : '#app');
}
// 濡備綍鐙珛杩愯寰簲鐢紵
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
export async function bootstrap(props) {
// 鍚姩
}
export async function mount(props) {
// 鎸傝浇
render(props);
}
export async function unmount(props) {
// 鍗歌浇
instance.unmount();
instance = null;
}
浣跨敤
涓诲簲鐢?/p>
<template>
<div>
<h1>涓诲簲鐢?vue3瀛愬簲鐢?鐨勫叏灞€鏁版嵁</h1>
<div>濮撳悕 : {{ $store.state.GlobalData.name }}</div>
<div>骞撮緞 : {{ $store.state.GlobalData.age }}</div>
<div>鏁伴噺 : {{ $store.state.GlobalData.count }}</div>
<el-button type="primary" @click="revampData">淇敼鍏ㄥ眬鏁版嵁</el-button>
</div>
</template>
<script setup>
import actions from '../actions';
const revampData = () => {
actions.setGlobalState({ name: '涓诲簲鐢? });
};
</script>
瀛愬簲鐢紙vue3锛?/p>
<template>
<div>鎴戞槸vue3椤圭洰</div>
<button @click="revampData">淇敼鍏ㄥ眬鏁版嵁</button>
</template>
<script>
import { getCurrentInstance } from 'vue';
export default {
name: 'Home',
components: {
HelloWorld,
},
setup() {
const { proxy } = getCurrentInstance();
const revampData = () => {
proxy.$setGlobalState({ name: 'vue3瀛愬簲鐢ㄥ簲鐢? });
};
return {
revampData,
};
},
};
</script>
[闇€姹俔 濡備綍閮ㄧ讲
qiankun閮ㄧ讲鐨勫笘瀛愮綉涓婃牴鏈壘涓嶅埌, 鍙兘鏄劅瑙夌畝鍗曞氨閮戒笉鎯宠浜嗗惂锛岀瑪鑰呰繖閲屼篃鏄儴缃蹭簡寰堝閬嶆墠璺戦€氾紝杩欓噷璇翠笅鎴戠殑鎬濊矾銆?/p>
鑰冭檻鍒颁富搴旂敤鍜屽瓙搴旂敤鍏辩敤鍩熷悕鏃跺彲鑳戒細瀛樺湪璺敱鍐茬獊鐨勯棶棰橈紝瀛愬簲鐢ㄥ彲鑳戒細婧愭簮涓嶆柇鍦版坊鍔犺繘鏉ワ紝鍥犳鎴戜滑灏嗗瓙搴旂敤閮芥斁鍦?code>xx.com/subapp/杩欎釜浜岀骇鐩綍涓嬶紝鏍硅矾寰?鐣欑粰涓诲簲鐢ㄣ€?/p>
姝ラ濡備笅锛?br> 1.涓诲簲鐢╩ain鍜屾墍鏈夊瓙搴旂敤閮芥墦鍖呭嚭涓€浠絟tml,css,js,static锛屽垎鐩綍涓婁紶鍒版湇鍔″櫒锛屽瓙搴旂敤缁熶竴鏀惧埌subapp鐩綍涓嬶紝鏈€缁堝锛?/p>
鈹溾攢鈹€ main
鈹? 鈹斺攢鈹€ index.html
鈹斺攢鈹€ subapp
鈹溾攢鈹€ sub-react
鈹? 鈹斺攢鈹€ index.html
鈹斺攢鈹€ sub-vue
鈹斺攢鈹€ index.html
2.閰嶇疆nginx锛岄鏈熸槸xx.com鏍硅矾寰勬寚鍚戜富搴旂敤锛寈x.com/subapp鎸囧悜瀛愬簲鐢?瀛愬簲鐢ㄧ殑閰嶇疆鍙渶鍐欎竴浠斤紝浠ュ悗鏂板瀛愬簲鐢ㄤ篃涓嶉渶瑕佹敼nginx閰嶇疆锛屼互涓嬪簲璇ユ槸寰簲鐢ㄩ儴缃茬殑鏈€绠€娲佺殑涓€浠絥ginx閰嶇疆浜嗐€?/p>
server{
listen 80; #渚﹀惉绔彛
server_name http://wzs.bengdada.com/; #瀹氫箟浣跨敤www.xx.com璁块棶
charset utf-8;
location / {
root /data/wzs/main; # 涓诲簲鐢ㄦ墍鍦ㄧ殑鐩綍
try_files $uri $uri/ /index.html;
}
location /subapp {
alias /data/wzs/subapp; # 涓诲簲鐢ㄦ墍鍦ㄧ殑鐩綍
try_files $uri $uri/ /index.html;
}
}
nginx -s reload鍚庡氨鍙互浜嗐€?
鏈枃鐗瑰湴鍋氫簡绾夸笂demo灞曠ず锛?br>
鏁寸珯锛堜富搴旂敤锛夛細wzs.bengdada.com/
鍗曠嫭璁块棶瀛愬簲鐢細
- subapp/micro-react
- subapp/micro-vue2
- subapp/micro-vue3
鏈€鍚?/h1>
鏈汉浠庡紑濮嬪紕寰墠绔弽澶嶆煡闃呭ぇ閲忚祫鏂欏拰瑙嗛锛岃俯杩囧緢澶氬潙锛屽繊涓嶄綇鎰熷徆 : 鐪熸槸瀛︽棤姝㈠.....
鏈€鍚庣殑鏈€鍚庯紝鍠滄鏈枃鐨勫悓瀛﹁繕璇疯兘椤烘墜缁欎釜璧為紦鍔变竴涓嬶紝闈炲父鎰熻阿鐪嬪埌杩欓噷銆?/p>