基座如何修改
1.安装qiankunyarn add qiankun
2.注册微应用并启动
1 2 3 4 5 6 7 8 9 10 11
| import { registerMicroApps, start } from 'qiankun'; registerMicroApps([ { name: 'child', entry: '//localhost:9000', container: '#container', activeRule: '/sub', } ]); start()
|
子应用如何修改
具体代码略,可参考官网qiankun
概要如下:
1.src目录下新增public-path.js,并在main.js中引入
2.main.js中抛出3个方法 bootstrap mount unmount
3.改造main中createapp的方式
4.打包配置修改(vue.config.js)
基座与子应用如何通信
基座与子应用的通讯只是用了APIinitGlobalState
initGlobalState返回一个MicroAppStateActions对象,它有三个属性:
- onGlobalStateChange:
(callback: OnGlobalStateChangeCallback, fireImmediately?: boolean) => void
, 在当前应用监听全局状态,有变更触发 callback,fireImmediately = true 立即触发 callback
- setGlobalState:
(state: Record<string, any>) => boolean
, 按一级属性设置全局状态,微应用中只能修改已存在的一级属性
- offGlobalStateChange:
() => boolean
,移除当前应用的状态监听,微应用 umount 时会默认调用
父应用如何做
1 2 3 4 5 6 7 8 9 10 11 12
| import { initGlobalState } from 'qiankun'; const state = { baiduinit: window, abc: 456 }
const actions = initGlobalState(state);
actions.onGlobalStateChange((state, prev) => { console.log(state, prev); });
|
子应用如何做
1.创建action.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| function emptyAction() { console.warn("Current execute action is empty!"); }
class Actions { actions = { onGlobalStateChange: emptyAction, setGlobalState: emptyAction, };
setActions(actions) { this.actions = actions; }
onGlobalStateChange() { return this.actions.onGlobalStateChange(...arguments); }
setGlobalState() { return this.actions.setGlobalState(...arguments); } }
const actions = new Actions(); export default actions;
|
2.在main.js mount方法中接收父应用的传值props
1 2 3 4 5 6
| import action from './qiankun/action' export async function mount(props) { console.log('[vue] props from main framework', props); action.setActions(props) render(props); }
|
3.在需要接收父应用传入的参数的地方引用action.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| import action from '@/qiankun/action' export default { name: 'Home', mounted() { action.onGlobalStateChange((state) => { console.log(state) }, true); }, methods:{ changeValue(){ action.setGlobalState({abc:789}) } } }
|
子应用可以修改通讯池,修改完会被基座监听到。
子应用引用了百度地图
子应用引用了第三方js库,在乾坤环境中会有跨域的问题,因为乾坤会把子应用的静态资源放到沙箱中,这样第三方js经过编译就会出现问题。解决方式是在基座中start方法中设置excludeAssetFilter,使qiankun不处理这部分js
1 2 3 4 5 6 7 8 9 10 11 12
| import { registerMicroApps, start } from 'qiankun'; start( { excludeAssetFilter: (urls) => { const whiteList = [] const whiteWords = ['baidu'] if (whiteList.includes(urls)) return true return whiteWords.some(w => urls.includes(w)) } } );
|
百度地图的初始化需要把init挂到window上,而在qiankun环境中window不是window了,我想到的办法是把window通过传参传给子应用,处理如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| import action from '@/qiankun/action' export default { mounted() { window.baiduinit = ()=>{ this.initBaiduMap(116.404, 39.915) } if(window.__POWERED_BY_QIANKUN__){ action.onGlobalStateChange((state) => { state.baiduinit.baiduinit = ()=>{ this.initBaiduMap(116.404, 39.915) } }, true); } this.createMap().then(()=>{ this.initBaiduMap(116.404, 39.915) }) }, methods: { createMap(){ return new Promise((resolve,reject)=>{ const map = document.getElementById('baidumap'); if(map){ resolve() return } console.log('create baidu map') let script = document.createElement('script'); script.id = 'baidumap'; script.type = 'text/javascript'; script.src = `https://api.map.baidu.com/api?v=3.0&ak=你的ak&callback=baiduinit`; document.body.appendChild(script); }) } ...
|
源码
https://gitee.com/clausliang/qiankun-demo