umi qiankun 微前端通信
配合 useModel 使用(推荐)
需确保已安装
@umijs/plugin-model或@umijs/preset-react
因为文档推荐的通信方式是 @umijs/plugin-model
但是 package.json 没有看到安装,以为不能用
结果看到入口 app.tsx 导出的 getInitialState 使用到 @umijs/plugin-initial-state

这个插件不可直接使用,必须搭配 @umijs/plugin-model 一起使用。
也就出说项目已经有在用了,只是看不到...
@umijs/plugin-model
约定在
src/models目录下的文件为项目定义的model文件
每个文件需要默认导出一个
function,该function定义了一个Hook,不符合规范的文件我们会过滤掉。

👇 src/models/xxx.js
import { useState } from 'react'
export default function useUser() {
const [user, setUser] = useState(null)
return {
user,
setUser
}
}models 目录下的文件名作为 state 的 nameSpace
👇 通过插件(安装后都从 umi 中引入) useModel(nameSpace) 使用
import { useModel } from 'umi'
export default () => {
const { user, setUser } = useModel('xxx')
console.log(user)
}@umijs/plugin-qiankun
微应用
微应用中会自动生成一个全局 model,可以在任意组件中获取主应用透传的 props 的值。
👆 全局 model 的 nameSpace 是 @@qiankunStateFromMaster
✨ 这里的 nameSpace 等同于 上面 @umijs/plugin-model 约定在 src/models 目录下的文件为项目定义的 model 文件
import { useModel } from 'umi'
function MyPage() {
const masterProps = useModel('@@qiankunStateFromMaster')
}主应用
在
src/app.ts里导出一个useQiankunStateForSlave函数,函数的返回值将作为 props 传递给微应用
👇 src/app.ts
export function useQiankunStateForSlave() {
const [masterState, setMasterState] = useState({
showFlag: false // <-- ✨ 设置初始值
});
return {
masterState,
setMasterState,
};
}通信
因为环境(插件依赖@umijs/plugin-qiankun、@umijs/plugin-model)已经完善
直接主应用入口定义并导出 useQiankunStateForSlave() 👇 src/app.ts
export function useQiankunStateForSlave() {
const [masterState, setMasterState] = useState({
showFlag: false // <-- ✨ 设置初始值
});
return {
masterState,
setMasterState,
};
}子应用环境(插件依赖@umijs/plugin-model)同样已经完善
👇 直接在业务页面组件中调用修改状态的 set 函数
import { useModel } from 'umi'
export default function Page1() {
const {masterState, setMasterState}= useModel('@@qiankunStateFromMaster')
setMasterState({showFlag: true}) // <-- ✨ 修改showFlag为true
}👆 即可使主应用的 showFlag 变为 true 触发主应用组件更新渲染
子应用独立运行时的状态控制
因为同时需要考虑子应用独立运行时的状态管理
因此子应用页面修改状态需要区分一下运行环境:
- 当运行在
qiankun微前端容器时,则修改主应用的state - 当独立运行时,则修改子应用项目的
state
尝试子应用创建 src/models/@@qiankunStateFromMaster.js 不侵入业务代码,由 umi 自动识别优先级:
- 子应用独立运行时,无主应用注入的全局
state,使用本地项目的src/models - 子应用运行在微前端容器时,自动无视子应用项目创建的
state,使用主应用的state
尝试失败 ❌, @umijs/plugin-model 不允许使用 @@qiankunStateFromMaster、@@initialState 做文件名(nameSpace)
那就只能侵入业务代码,运行时判断当前子应用运行的环境,使用不同的 state
子应用创建一个 state (和主应用的状态保持一致)
👇 src/models/xxx.js
import { useState } from 'react'
export default function subAppModel() {
const [masterState, setMasterState] = useState({
showFlag: false
})
return {
masterState,
setMasterState
}
}👇 封装一个 Hook 根据运行环境操作对应的 state
import { useQianKun } from "@/utils/hooks"
import { useModel } from "@umijs/max"
export function useState() {
const inqiankun = useQianKun() // 判断子应用运行环境
const stateModelNamespace = inqiankun ? '@@qiankunStateFromMaster' : 'xxx'
return useModel(stateModelNamespace)
}👇 子应用页面使用
const { setMasterState } = useState()
setMasterState({showFlag: true})