1.安裝qiankun
yarn add qiankun 或者 npm i qiankun -S
2.創建應用
.創建主應用 vue create qiankun-base .創建React子應用 create-react-app qiankun-react .創建Vue子應用 vue create qiankun-vue
3.進行主應用(qiankun-base項目)的配置
安裝:npm i element-ui qiankun view-design vue-router
src目錄下創建router.js文件,加入如下代碼
import Vue from "vue";// 引入vue import Router from "vue-router";// 引入vue-router import Home from './components/HelloWorld.vue'; Vue.use(Router);// 使用路由 const router = new Router({// 實例化router對象 mode: "history",// 使用hash路由,帶#號 base: process.env.BASE_URL, routes: [// 路由的配置項 { path: "/", component: Home },// /路徑對應Home組件 ], }); export default router;// 拋出路由
main.js中
entry:配置是兩個子項目的域名和端口,必須確保兩字子項目運行在這兩個端口上面
container就是我們的容器名,就是我們子應用掛載的節點,相當於Vue項目里面的app節點
activeRule就是我們的激活路徑,根據路徑來顯示不同的子應用
import Vue from 'vue' import App from './App.vue' import router from './router'//相關路由配置 import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; import ViewUI from 'view-design'; import 'view-design/dist/styles/iview.css'; Vue.use(ElementUI); Vue.use(ViewUI); import {registerMicroApps,start,initGlobalState} from 'qiankun'; // 初始化 state let state = { a: 1, b: 2 } const actions = initGlobalState(state); // 主項目項目監聽和修改 actions.onGlobalStateChange((state, prev) => { // state: 變更后的狀態; prev 變更前的狀態 console.log(state, prev); }); actions.setGlobalState({a:3}); const apps = [ { name:'vueApp', // 應用的名字 entry:'//localhost:10000', // 默認會加載這個html 解析里面的js 動態的執行 (子應用必須支持跨域)fetch container:'#vue', // 容器名 activeRule:'/vue/', // 激活的路徑 props:{a:1} }, { name:'reactApp', entry:'//localhost:3000', // 默認會加載這個html 解析里面的js 動態的執行 (子應用必須支持跨域)fetch container:'#react', activeRule:'/react/', } ] registerMicroApps(apps,{
start({ prefetch:false // 取消預加載 });// 開啟 new Vue({ router, render: h => h(App) }).$mount('#app')
APP.vue中
<template>
<div>
<el-menu :router="true" mode="horizontal">
<!--基座中可以放自己的路由-->
<el-menu-item index="/">Home</el-menu-item>
<!--引用其他子應用-->
<el-menu-item index="/vue/">vue應用</el-menu-item>
<el-menu-item index="/react/">react應用</el-menu-item>
</el-menu>
<router-view ></router-view>
<div id="vue"></div>
<div id="react"></div>
<!--<img src="./assets/zzh.jpg" alt="">-->
</div>
</template>
src目錄下新建vue.config.js文件
module.exports = { // 基本路徑 publicPath: './', // 輸出路徑 outputDir: 'dist', // 靜態資源 assetsDir: './', // eslint-loader是否在保存時候檢查 lintOnSave: true, // 服務項配置 devServer: {
port: 8001, //設置當前項目的端口號 // 設置代理proxy proxy: { "/xx": { target: "http://its.dev.etongeis.com:38001", // 都昌服務器 changeOrigin: true, ws: true, pathRewrite: { "^/xx": "" // 去掉接口地址中的api字符串 } } } } }
4.配置qiankun-Vue 子項目
安裝:npm i vue-router
main.js文件中加入以下代碼
import Vue from 'vue' import App from './App.vue' import router from './router' let instance = null; //掛載實例 function render(){ instance = new Vue({ router, render: h => h(App) }).$mount('#app') } //判斷當前運行環境是獨立運行的還是在父應用里面進行運行,配置全局的公共資源路徑 if(window.__POWERED_BY_QIANKUN__){ __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__; } //如果是獨立運行window.__POWERED_BY_QIANKUN__=undefined if(!window.__POWERED_BY_QIANKUN__){ render() } //最后暴露的三個方法是固定的,加載渲染以及銷毀 export async function bootstrap(){} export async function mount(props){ render(); } export async function unmount(){ instance.$destroy(); }
src目錄下創建router.js文件加入以下代碼
import Vue from 'vue' import VueRouter from 'vue-router' import Home from './components/HelloWorld.vue' Vue.use(VueRouter) const routes = [ { path: '/', name: 'Home', component: Home } ] const router = new VueRouter({ mode: 'history', base: '/vue', routes }) export default router
跟目錄下創建vue.config.js文件加入以下代碼
module.exports = {
port:10000,//這里的端口是必須和父應用配置的子應用端口一致 headers:{ //因為qiankun內部請求都是fetch來請求資源,所以子應用必須允許跨域 'Access-Control-Allow-Origin':'*' } }, configureWebpack:{ output:{ //資源打包路徑 library:'vueApp', libraryTarget:'umd' } } }
5.配置qiankun-react子項目
安裝:npm i react-router-dom@5.2.0 react-app-rewired
src目錄下index.js文件加入如下代碼:
import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; function render(){ ReactDOM.render( <React.StrictMode> <App /> </React.StrictMode>, document.getElementById('root') ); } if(!window.__POWERED_BY_QIANKUN__){ render(); } export async function bootstrap(){ } export async function mount() { render() } export async function unmount(){ ReactDOM.unmountComponentAtNode( document.getElementById('root')); }
根目錄下創建config-overrides文件並加入以下代碼:
module.exports = { webpack:(config)=>{ config.output.library = 'reactApp'; config.output.libraryTarget = 'umd'; config.output.publicPath = 'http://localhost:3000/'; return config; }, devServer:(configFunction)=>{ return function (proxy,allowedHost){ const config = configFunction(proxy,allowedHost); config.headers = { "Access-Control-Allow-Origin":'*' } return config } } }
App.js
import React from 'react'; import logo from './logo.svg'; import './App.css'; import { BrowserRouter, Route, Link } from 'react-router-dom' function App() { return ( <BrowserRouter basename="/react"> <Link to="/">首頁</Link> <Link to="/about">關於頁面</Link> <Route path="/" exact render={() => ( <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> )}></Route> <Route path="/about" render={()=><h1>about頁面</h1>}></Route> </BrowserRouter> ); } // qiankun 無關的技術棧 export default App;
修改package.json(npm install react-app-rewired -D)
"scripts": { "start": "react-app-rewired start", "build": "react-app-rewired build", "test": "react-app-rewired test", "eject": "react-app-rewired eject" },
參考地址:
https://blog.csdn.net/a1998321/article/details/108758033
https://juejin.cn/post/6844904158085021704#heading-1
https://blog.csdn.net/qq_37947438/article/details/107666817
