微前端框架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一下,完成这个需求。