1.效果图:
从项目A到项目B,就像是普通的页面跳转一样,但其实是两个项目之间来回“横跳”
2.为什么要用:
2.1.项目越来越大,不好维护时
2.2.如果你不忙,想使用最新的技术又不想影响开发。
比如说我,现在的项目用的是vue2+ElementUI,使用了乾坤微前端后,可视化大屏用的是vue3.2+TS+vite,然后还有一个页面用的是react Hooks+ts,这样一个项目我就用了三套技术栈,对于提升技术很有帮助
2.3.比如好不容易找到一个轮子,发现人家用的技术栈和自己的项目不一样时
2.4.用起来简单不算麻烦,目前社区逐步成熟了
3.怎么用:
官网有对于vue、react、以及其他的配置过程
我是以vue2+element UI+webpack为主项目,写一个副项目为vue3+element-plus+vite
3.1 原项目的步骤:
第一步,安装依赖,在你的原项目:
$ yarn add qiankun # 或者 npm i qiankun -S
第二步,main.js中,在你的原项目:
import Vue from "vue"; import App from "./App.vue"; import router from "./router"; import store from "./store"; import { registerMicroApps, start } from "qiankun"; //++++++++++ Vue.config.productionTip = false;//++++++++++ new Vue({ router, store, render: (h) => h(App), }).$mount("#app"); // 在主应用中注册子应用 //++++++++++ registerMicroApps([ { name: "vueApp", //子应用名称-自己设置 entry: "//localhost:8091", //子应用启动的地址-自己设置 container: "#container", // 子应用在主应用的容器名称-自己设置 activeRule: "/app-vue", // 路由地址,后面用push()或者route.link.to-自己设置 props: { data: "child子应用", }, //传参 }, ]); // 启动 start();
第三步,vue.config.js,在你的原项目:
module.exports = { devServer: { port: 8090, //你自己项目的端口号 headers: { "Access-Control-Allow-Origin": "*", // 允许跨域访问子应用页面 ++++++++++ }, }, };
第四步:app.js,在你的原项目:
这一步不必按照我的来,其实就是你自己自行加一个跳转的链接,用$router.push()或者route.link.to跳过去
<div id="app"> <span><router-link to="/">点击跳转到父页面</router-link></span> <span><router-link to="/app-vue">点击跳转到子页面</router-link></span> <router-view /> <div id="container"> <!-- 子应用位置 --> </div> </div>
至此,主应用配置完毕
3.2 接下来是配置子项目步骤:
第一步,在src文件夹下新建public-path.js文件,并添加如下代码
if (window.__POWERED_BY_QIANKUN__) { __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__; }
这一步,90%概率会遇到webpack_public_path 未定义,这是因为EsLint的检测机制,所以我们需要在package.json中的eslintConfig中进行如下配置
"eslintConfig": { ...... "globals": { "__webpack_public_path__": true } },
第二步,main.js中,在你的子项目:
注意下:这里和官网的配置不一样,这里很容易报错,按照我这个来就行
还有一个注意点:
还有要注意的是我这里修改了
#app
为#app-vue
,原因为#app在主应用中已使用,会冲突,所以对应的index.html与App.vue中也应当修改为#app-vue
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-vue") : "#app-vue"); } // 独立运行时 if (!window.__POWERED_BY_QIANKUN__) { render(); } export async function bootstrap() { console.log("[vue] vue app bootstraped"); } export async function mount(props) { console.log("[vue] props from main framework", props); render(props); } export async function unmount() { instance.$destroy(); instance.$el.innerHTML = ""; instance = null; } new Vue({ router, render: (h) => h(App), }).$mount("#app-vue");
第三步,配置子应用跨域,,在你的子项目的vue.config.js文件,并添加如下代码
const { name } = require("./package"); module.exports = { devServer: { port: 8091, //子应用启动端口号,不可随意修改,与上文中父应用注册的子应用端口号对应 headers: { "Access-Control-Allow-Origin": "*", //循序跨域 }, }, configureWebpack: { output: { library: `${name}-[name]`, libraryTarget: "umd", // 把微应用打包成 umd 库格式 jsonpFunction: `webpackJsonp_${name}`, }, }, };
第四步,在你的子项目配置路由,打开src/router文件夹下的index.js文件,将以下代码
将:
1. const router = new VueRouter({ 2. routes, 3. });
修改为:
const router = new VueRouter({ // 这里和主应用中注册子应用时的activeRule对应 base: window.__POWERED_BY_QIANKUN__ ? "/app-vue" : "/", mode: "history", routes, });
第五步,修改app.vue和index.html中绑定的id,在你的子项目:
1. <template> 2. <div id="app-vue">我是子应用</div> 3. </template>
到这就完成了,我这里还遇到一个不大不小的问题:
子项目的样式有些错乱,检查后发现子项目的font-size继承了父项目的font-size,而父项目用了rem适配,处理的点是body和html的样式中设置font-size的值,解决了。