文章描述
随着工作时间的增加,发现公司的项目逐渐多了起来,有一个项目比较庞大,是需要集成多个子系统而形成的大项目。其中便是使用微前端的概念qiankun框架来集成其他多个子项目的。接下来,一起来看一下qiankun框架的具体使用方法吧。
更具体的使用方法请参考qiankun官网
主要内容
主应用
下载依赖
npm i qiankun -S
我们只需要再主应用中下载即可,需要注意的是,下载当前的依赖对node的版本也有限制,我第一次安装就踩坑了
要求的node版本是"^12.22.0 || ^14.17.0 || >=16.0.0"之内,不能高不能低,挺无语的哈...
添加配置
在main.js文件夹同级下创建registerApp.js文件(重要)
import { registerMicroApps, start } from 'qiankun';// 配置加载中的钩子函数
const onLoad = ()=>{console.log("加载中");
}
registerMicroApps([{name: 'appChild', // 子程序的name名,对应的是子程序中package中的name名字,唯一的entry: '//localhost:3002', // 子程序的路径,就是访问子程序的路径container: '#container', // 希望将子应用放在哪个容器内activeRule: '/ortherSystem', // 子程序的路由匹配规则,如当主程序中访问路由/ortherSystem时,框架会自动将子应用的内容加载到上面的容器内loader:onLoad, // 当前子应用加载时运行的函数props:{ // 希望给子应用传递的值,在子应用暴露出的mount等函数中可拿到text:"你好,我是主应用" }}
],{beforeLoad:()=>{console.log("加载前");},beforeMount:()=>{console.log("挂载前");},afterMount:()=>{console.log("挂载后");},beforeUnmount:()=>{console.log("销毁前");},afterUnmount:()=>{console.log("销毁后");},
});start({sandbox: {strictStyleIsolation: true, // 开启shadow dom样式隔离模式},
});
当然如果,如果我们需要手动添加子应用程序时,可以用下面这个函数,这个函数可以让我们在某个js函数中加载子应用。
import { loadMicroApp } from 'qiankun';loadMicroApp({name: 'app',entry: '//localhost:7100',container: '#yourContainer',
});
对了,当前创建的文件记得要在main.js文件中引入哦
打包配置
在vue.config.js中也需要添加相关的打包配置
const { defineConfig } = require('@vue/cli-service')
const packageName = require('./package.json').name;
module.exports = defineConfig({devServer: {host:'localhost',port:3001,headers:{'Access-Control-Allow-Origin':'*',},publicPath:'./',configureWebpack:{output: {library: `${packageName}`,libraryTarget: 'umd',chunkLoadingGlobal: `webpackJsonp_${packageName}`,},}
})
请注意'Access-Control-Allow-Origin':'*'配置一定需要,要不会有跨域错误。
子应用
子应用中不需要下载相关的依赖,只需要安装要求进行配置即可
配置main.js
根据官网要求,我们需要在子应用的main.js文件中添加并导出几个函数,分别是bootstrap,mount,unmount等函数。main.js的文件具体写法如下,被我改造了一下
import { createApp } from 'vue'
import App from './App.vue'// 引入路由
import router from './router/router'let app = null;
const render = (props)=>{app = createApp(App);app.use(router);app.use(ElementPlus);app.mount(props && props.container ? props.container.querySelector("#app") : '#app');
}
/*** bootstrap 只会在微应用初始化的时候调用一次,下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。* 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。*/
export async function bootstrap(props) {console.log(props,'props app bootstraped');
}// 这个变量是qiankun框架暴露给全局的,判断当前应用是否使用qiankun框架了
if(!window.__POWERED_BY_QIANKUN__){render()
}
/*** 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法*/
export async function mount(props) {console.log(props,"props");render(props)
}
/*** 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例*/
export async function unmount(props) {app.unmount()app = null;
}/*** 可选生命周期钩子,仅使用 loadMicroApp 方式加载微应用时生效*/
export async function update(props) {console.log('update props', props);
}
添加文件
创建public-path.js、.env.development、.env.production等文件
1、.env.development
VUE_APP_PORT = 3002
2、env.production
VUE_APP_PORT = 3002
3、public-path.js(该文件主要用于动态修改publicPath属性)
(function() {if (window.__POWERED_BY_QIANKUN__) {if(process.env.NODE_ENV === 'development') {__webpack_public_path__ = `//localhost:${process.env.VUE_APP_PORT}${process.env.BASE_URL}`;return;}__webpack_public_path__ = window.INJECTED_PUBLIC_PATH_BY_QIANKUN__;}
})();
该文件记得在main.js中引入哦
打包配置
1、在package.json文件中,将name修改为主应用中注册所使用的name名。
2、在路由配置中,将路由的baseUrl改成主应用中注册的路由规则的值,如:
// 我得主应用的路由规则为 /ortherSystem
const routerHistory = createWebHistory('/ortherSystem')
3、在vue.config.js里面配置
const { defineConfig } = require('@vue/cli-service')
const packageName = require('./package.json').name;module.exports = defineConfig({devServer: {host: 'localhost',headers:{'Access-Control-Allow-Origin':'*',},port: process.env.VUE_APP_PORT,},configureWebpack:{output: {library: `${packageName}`,libraryTarget: 'umd',chunkLoadingGlobal: `webpackJsonp_${packageName}`,},}
})
运行结果
好了,进行了上面的几步后我们应该就可以看到基本的效果了,
报错经历
1、node版本不匹配,这是我们需要换适合的node版本了,推荐是"^12.22.0 || ^14.17.0 || >=16.0.0"之间。
2、当我们的主应用和子应用都准备好了,但是效果还是不出来,查看控制台发现是跨域了,这是因为端口后ip不同,我们需要再vue.config.js文件的devServer下添加相关配置
headers:{'Access-Control-Allow-Origin':'*',},
3、 子应用中路由不匹配,子应用中匹配好的路由,子应用单独启动能正常跳转,但是使用qiankun框架使用就无法正常匹配了,报404未找到页面
这大概率是因为你在主应用中将添加子应用的容器使用router-view这个标签渲染了,我们不要用这个标签,可以的话在组件中直接引入渲染即可
<template><!-- 不要要用这种方法 --><!-- <router-view></router-view> --><!-- 用这种方法渲染homePage组件,子应用的容器就在homePage组件中 --><homePage></homePage>
</template><script setup>
import homePage from '@/components/homePage.vue'
</script>
4、 样式问题,在子应用中样式是正常的,但是在主应用中,子应用的样式丢失了,而且在我还设置了strictStyleIsolation: true模式,样式还是很神奇的消失了,
网上查询了好多方法,最后用审查元素查看发现子应用也正常被shadow-root包裹起来了,结果发现是子应用中,挂载元素时自己写错了,在子应用中的render函数应该这样写
let app = null;
const render = (props)=>{app = createApp(App);app.use(router);app.use(ElementPlus);// 错误// app.mount(props && props.container ? props.container : '#app');// 正常app.mount(props && props.container ? props.container.querySelector("#app") : '#app');
}
props是qiankun框架提供的参数,里面包含了我们注册时提供的子应用名和主应用中要挂载的容器,但是我们不能直接将子应用挂载到props.container容器中,这样会将里面内置的标签属性给覆盖掉,导致样式不生效
最终感想
这只是qiankun框架的基本使用方式,具体的方法和更多详情可以去官网查看,官网写的很清楚的,当前属于我个人的笔记,也希望通过这篇文章可以帮到同行的朋友
如果以上写的内容有什么错误的地方,欢迎各位大佬来指点,我发现后一定尽快修改