// index.tsx
import { registerMicroApps, start } from 'qiankun'
(window as any).__POWERED_BY_QIANKUN_PARENT__ = true
// 如果已使用qiankun,则主应用不需要以下配置
const childApps = [{
name: 'child-app',
entry: '//localhost:8000',
container: '#root',
activeRule: '/sub/test'
}]
registerMicroApps(childApps)
start()
// App.tsx
const Test = lazy(() => import("@/views/test"));
<Switch>
...
<Route component={Test} path={`/sub/test`} exact></Route>
</Switch>
// child.tsx
// 子应用加载子应用,替换iframe
import {FC, useCallback, useEffect, useRef} from 'react'
import { loadMicroApp } from 'qiankun'
const Child:FC = () => {
const Ref = useRef(null)
const handleLoadApp = useCallback(() => {
return loadMicroApp({
name: 'child-app,
entry: //localhost:8000',
container: Ref.current!,
props: {
store: {}
}
})
}, [store])
useEffect(() => {
const microApp = handleLoadApp()
microApp.mountPromise.then(() => {
console.log('加载成功')
}).catch(() => {
console.log('加载失败')
}).finally(() => {
console.log('finally')
})
/**
* 切换页面会引发 element 不存在问题
* 可使用 react-keepalive-router 缓存当前组件解决
*/
// return () => {
// 卸载子应用
// !!microApp && microApp.unmount()
// }
},[handleLoadApp])
return <div ref={Ref} />
}
如果是路由级别的嵌入,最后需要应用之间统一路由模式,反之不需要。
切换路由可能导致styled-components
自定义样式,子应用需要包裹一下
// 子应用index.tsx
...
ReactDOM.render(
<StyleSheetManager disableCSSOMInjection>
<BrowserRouter basename="/">
....
<BrowserRouter>
</StyleSheetManager>
)