在qiankun官方文档的API中有关于应用通信的方法介绍,
API 说明 - qiankun里的 initGlobalState
定义全局状态,并返回通信方法。这里简单记录一下vue项目中实际的应用。
1、在主应用中定义全局状态
主应用中新增action js文件,可以导出供其他组件使用
// 引入qiankun的应用间通信方法initGlobalState,设置全局状态actions并导出供其他组件使用
// 微应用通过 props 获取通信方法
import { initGlobalState } from 'qiankun';
// 定义初始化全局状态,例如用户信息等
const initialState = {
userInfo: {
userName: '',
token: '',
role: '',
},
};
const actions = initGlobalState(initialState); // 初始化state
//监听actions全局公共状态数据的变化,主应用或子应用更改全局状态时会触发
actions.onGlobalStateChange((state,prevState) => {
// console.log(state, prevState);
// 这里可以做一些更新全局数据的工作,例如更新store中的数据
});
export default actions;
2、在组件中使用
例如在主应用中登录后,需要将用户信息传递给子应用
import actions from "./actions"
...
// 登录
const onSignIn = () => {
getPublicKey().then((res) => {
...
loginApi({ info }).then((res) => {
const data = {
username: res.username,
token: res.token,
role: res.role
};
// 修改全局状态,此时会触发onGlobalStateChange
actions.setGlobalState(data);
});
});
};
3、在注册子应用时传递
props中传递数据,这里是手动注册方式
import actions from '@/action.js';
import useUserInfoStore from '@/store/modules/userInfo';
...
// 获取store中的数据
const userInfoStore = useUserInfoStore();
// 手动注册子应用
const loadApp = () => {
microApp = loadMicroApp({
name: 'ontologyApp', // 子应用名称
entry: '//localhost:8501', // 子应用的baseURL
container: '#main-container', // 用来装子应用的容器ID
props: { actions, userInfo: userInfoStore.userInfo },// 传递数据
});
4、在子应用中接收
可以在qiankun生命周期mount中接收,因为应用每次进入都会调用 mount 方法
renderWithQiankun({
mount(props) {
// 这里的props包含注册子应用时传递的内容,也包括固定的一些参数
console.log('子应用', props);
render(props);
// 在这里接收数据,可以做存入store的操作
// store.commit("updateUserInfo",props);
//注册vue全局方法,
//如需要在子应用中更改或者监听主应用的全局状态的话需要注册全局方法
app.config.globalProperties.$onGlobalStateChange = props.actions.onGlobalStateChange;
app.config.globalProperties.$setGlobalState = props.setGlobalState;
//这里用props.actions.onGlobalStateChange或者props.onGlobalStateChange都可以
},
...
});
5、在子应用中修改和监听全局数据
在组件中使用全局注册的监听方法和set方法
import {
ref, reactive, toRefs, onMounted, defineComponent, getCurrentInstance,
} from 'vue';
...
setup() {
const { proxy } = getCurrentInstance();
// 改变主应用的全局状态,注意修改时需要带上所有的参数,如果只修改部分参数,其余参数
会被置为初始值的状态
const changeParent = () => {
proxy.$setGlobalState({
userInfo: { userName: '子应用修改', token: 123, role: 2 },
});
};
onMounted(() => {
// 监听主应用全局状态的改变
proxy.$onGlobalStateChange((cur, pre) => {
console.log(cur, pre);
});
});
}
总结:
主应用注册的全局状态可以传到各个子应用,主应用和各个子应用都可以修改和监听状态值,但若子应用间想要互相修改数据的话无法直接修改,需要通过主应用来作为中转,即子应用1修改主应用状态,主应用传递给子应用2新的状态值。