一、实现方案
1.1 思路
- 主应用中新增页面,作为子应用加载入口
- 页面添加DOM元素作为子应用的容器节点
- 主工程点击菜单跳转页面,用官网提供的API
loadMicroApp(app, configuration?)
加载子应用 - 通知子应用
setGlobalState(state)
- http部分,主应用服务端提供转发接口/appProxy/child;修改子应用拦截器,所有子应用请求URL重写为/appProxy/child,子应用的请求URL、methods等信息作为参数传递;主应用服务端转发http请求
- 子应用订阅消息
onGlobalStateChange(callback: OnGlobalStateChangeCallback, fireImmediately?: boolean) => void
- 子应用路由跳转到指定页面
1.2 业务流程图
二、代码实现
2.1主应用
安装 qiankun
npm install qiankun -S
- 初始化方法micro.js
import { initGlobalState,loadMicroApp } from 'qiankun'
let state = {
user:null
}
const { setGlobalState,onGlobalStateChange } = initGlobalState(state)
export const onGlobalStateChangeMicro = onGlobalStateChange
export const setGlobalStateMicro = setGlobalState
- 新建页面组件,作为子应用的入口,调用
loadMicroApp 、setGlobalStateMicro
<template>
<div>
<div id="child"></div>
</div>
</template>
<script>
import { loadMicroApp } from 'qiankun'
import { setGlobalStateMicro } from '@/micro/micro.js'
export default {
mounted: {
loadMicroApp({
name:'child', //与子应用的配置的library一致
entry:'//localhost:9000/', // 微应用的入口
container:'#child' //微应用容器
},{
sandBox:{
strictStyleIsolation: true // 开启严格的样式隔离模式
}
})
setGlobalStateMicro({
path:'/childpage', //子应用页面路由path
query:{} //路由跳转携带参数
})
}
}
</script>
2.2 子应用
新建publicPath.js文件,并在main.js中引入
if(window.__POWERD_BY_FUSION){
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_FUSION__
}
- main.js声明并导出生命周期函数
export async function bootstrap(){}
export async function mount(){}
export async function unmount(){}
- 修改webpack配置
output:{
library:'child',
libraryTarget:'umd',
jsonpFunction:'webpackJsonp_child'
}
- 修改路由配置,不能出现通配符*
- 在mount生命周期中,接收主工程数据,跳转A页面
export asunc function mount(props){
render(props)
props.onGlobalStateChange((state,prev)=>{
let { path,query } = state
setTimeout(()=>{
vm.$router.push({path,query})
})
},true)
}
- http请求处理,修改axios请求拦截器
axios.interceptors.request.use((requestConfig)=>{
const isMicro = !!window.__INJECTED_PUBLIC_PATH_BY_FUSION__
IF(isMicro){
if(requestConfig.method == 'get'){
let _url = requsetConfig.url
let _methods = 'get'
let arr = []
for(let p in requestConfig.params){
arr.push(`${p}=${requestConfig.params[p]}`)
}
requsetConfig.url = '/appProxy/child'
requestConfig.params = {
_url:_url + arr.join('&'),
_methods
}
return requestConfig
}else{
let _url = requsetConfig.url
let _methods = 'post'
requsetConfig.url = '/appProxy/child'
requestConfig.params = {
_url,_methods
}
return requestConfig
}
}
return requestConfig
})
- 子应用独立运行
let vm = null
function render (props = {}){
const { container } = props
vm = new Vue({
router,
store,
render:h=>h(App)
}).$mount(container ? container.querySelector('#child') : '#child')
}
if(!window.__POWERED_BY_FUSION__){
render()
}
更多配置可参考qiankun官方文档