qiankun框架的使用-Vue基座
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