微前端框架qiankun的备忘笔记。
之前工程中整合配置都成功了,两个月过去后,做新项目竟然又忘记怎么搞了,在此把相关内容做一下记录,避免再次出现这种尴尬的情况。
官方资料
参考项目
代码示例
vue3的子应用实现
配置main.js和vue.config.js两个地方就可以了。
main.js
// import './public-path';import { createApp } from 'vue';import { createRouter, createWebHashHistory } from 'vue-router';import App from './App.vue';import routes from './router';import store from './store';if (window.__POWERED_BY_QIANKUN__) {// eslint-disable-next-line no-undef__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;}let router = null;let instance = null;function render(props = {}) {const { data, methods } = props;router = createRouter({history: createWebHashHistory(),routes,});instance = createApp(App);instance.use(router);instance.use(store);instance.mixin({data() {return {...data,};},methods,});instance.mount('#biApp');}if (!window.__POWERED_BY_QIANKUN__) {render();}export async function bootstrap() {console.log('%c ', 'color: green;', 'vue3.0 app bootstraped');}function storeTest(props) {props.onGlobalStateChange &&props.onGlobalStateChange((value, prev) => console.log(`[onGlobalStateChange - ${props.name}]:`, value, prev),true);props.setGlobalState &&props.setGlobalState({ignore: props.name,user: {name: props.name,},});}export async function mount(props) {console.log('mount props:', props);const methods = {};if (props.data.fns) {props.data.fns.forEach(item => {methods[item.name] = item;});delete props.data.funs;}storeTest(props);render({...props,methods,});instance.config.globalProperties.$onGlobalStateChange = props.onGlobalStateChange;instance.config.globalProperties.$setGlobalState = props.setGlobalState;}export async function unmount() {instance.unmount();instance._container.innerHTML = '';instance = null;router = null;}
注意事项:
- 建议根组件挂载的元素id不要使用默认的#app,有可能会出现子应用覆盖了主应用的#app。
vue.config.js
devServer: {hot: true,disableHostCheck: true,port,overlay: {warnings: false,errors: true,},headers: {'Access-Control-Allow-Origin': '*',},proxy: {'/biconfigApi': {target: 'http://localhost:7001',changeOrigin: true,pathRewrite: { '^/biconfigApi': '/api' },},},},
注意事项:
- 注意写disableHostCheck和Access-Control-Allow-Origin,不然有可能会跨域加载不出来。
- api的前缀最好跟主应用的区分开来,不然有可能会被主应用捕捉走。
遇到的问题
- 在主应用的某个页面中,是否可以加载多个子应用的页面。
- 看官方文档是说“基于路由只能加载一个子应用页面”,同时提供了手动加载的函数。但是经过尝试还是不行,手动加载后,路由地址依然会发生变化,依然只能加载一个子应用页面。
- 看github上的Issues上也有人有同样需求:
- 好在可以根据Issues中用户提供的iframe方案hack一下,完成这个需求。
