使用场景: 根据不同业务场景,会创建多个独立的项目工程,使用微前端可以快速聚合独立工程,搭建统一应用登录平台
创建微前端基座
当前使用 react 作为微前端基座
创建 react 项目
npx create-react-app my-app
配置 react router
npm install react-router-dom@6.21.2
import Login from "./view/login"
import Home from "./view/home"
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<HashRouter>
<Routes>
<Route path='/home' element={<Home/>}/>
<Route path='/' element={<Login/>}/>
</Routes>
</HashRouter>
</React.StrictMode>
)
安装 micro-app 依赖
npm install micro-app
在 main.tsx 文件中初始化
import microApp from '@micro-zoe/micro-app';
microApp.start()
此时可以在基座项目中引用子项目的地址,示例如下
import {useEffect} from "react"
import styled from 'styled-components'
import "./index.css"
import microApp from '@micro-zoe/micro-app'
import {useNavigate} from "react-router-dom"
const HomeContainer = styled.div`
width: 100%;
height: 100%;
`
const Home = ()=>{
const navigate = useNavigate();
/**接受子应用参数 */
useEffect(()=>{
microApp.clearDataListener("my-app");
microApp.addDataListener("my-app",(data:any)=>{
if(data.type === "logout"){
navigate("/",{replace:true})
}
})
},[])
return (
<HomeContainer>
/*此时的 name 属性的 my-app 值,作为此基座的id*/
<micro-app name='my-app'
url='http://localhost:5174/'
disableScopecss='false'
iframe></micro-app>
</HomeContainer>
)
}
export default Home
上面代码中开启了 iframe 模式,在使用过程中 react 子项目不存在可以使用默认模式, react + vue组合需要使用 iframe 模式才可以加载到子应用
根据官网文档中建议使用 history 模式 ,在实际使用过程中双基座都是 hash 也可以正常部署和使用
创建子应用项目
子项目使用 vite + Vue3 创建,创建项目的过程使用 vite 官方命令构建即可,在此不做展开
在子应用中不需要安装 micro-app 依赖,可在window 对象中和基座项目进行通信
基座向子应用通信
基座项目
const handelSubmit = ()=>{
microApp.setData('my-app', {type:"logoStatus",data:"hello Vue")
}
子应用监听
<script lang="ts" setup>
const dataListener = (data:dataListenerType)=>{
if(data.type === "logoStatus"){
console.log(data.data) /*hello vue*/
}
}
const comm = ()=>{
(window as any).microApp.addDataListener(dataListener,true)
}
comm()
/**页面结束后销毁 */
onUnmounted(()=>{
(window as any).microApp.removeDataListener(dataListener)
})
</script>
子应用向基座应用通信
子应用
<script lang="ts" setup>
const logout = ()=>{
/**微前端子应用和主应用通信 */
(window as any).microApp.dispatch({type: 'logout'})
}
</script>
基座应用
const Home = ()=>{
useEffect(()=>{ /*利用 hooks 的特性,在页面初始化的时候监听 my-app 通信*/
microApp.clearDataListener("my-app"); /*清楚之前的监听实例*/
microApp.addDataListener("my-app",(data:any)=>{ /*重新监听my-app的通信状态*/
if(data.type === "logout"){
navigate("/",{replace:true})
}
})
},[])
}
微前端样式隔离
在基座应用中因为 name 属性是唯一的 ,可以利用 name 属性做一些样式隔离,控制子应用中的样式问题
示例
micro-app[name=my-app],micro-app[name=my-app] micro-app-body,micro-app[name=my-app] #app{
width: 100%;
height: 100%;
}
micro-app[name=my-app] button{
color:#fff !important;
}
micro-app[name=my-app] .ant-btn{
padding: 4px 15px !important;
}
micro-app[name=my-app] .ant-btn-circle{
padding: 0px !important;
}