前言
该项目是 vue2 基座 + vue2 子模块(module federation) + vue3 子应用,需要解决 vue2 基座与 vue3 子应用之间的 vuex 数据共享。
思路:借助于 qiankun 内 initGlobalState
去生成一份共享数据,通过传递给子应用 setGlobalState
和 onGlobalStateChange
方法去让子应用可以修改共享数据和监听到共享数据改变之后,子应用通过 onGlobalStateChange
去修改其 vuex 内的数据。
实现
// 基座
import { initGlobalState } from 'qiankun';
// 初始化共享数据
const { onGlobalStateChange } = initGlobalState({value: '1'})
onGlobalStateChange((state, prev) => {
// state: 变更后的状态, prev 变更前的状态, 这步可以不加,只是为了调试
console.log('main-app onGlobalStateChange', state, prev)
})
复制代码
// vue3 子应用
// store/index.js
import { createStore } from 'vuex'
import cloneDeep from 'lodash/cloneDeep';
const state = {
store: {}
}
const getters = {
value: state => state.store.value
}
const mutations = {
initStore(state, data) {
state.store = data
},
setStore(state, datay) {
state.store = {
...state.store,
...data
}
}
}
const actions = {
increment ({ commit }) {
commit('setStore', {
value: '2'
})
}
}
const initStore = {
actions,
getters,
state,
mutations,
modules: {},
strict: false,
plugins: [],
}
function initStore(props) {
const QiankunDataSharePlugin = (store) => {
let prevState = cloneDeep(store.state)
// 当 store 初始化后调用,使用 vuex 插件去监听每一次的数据变化,将变化后的数据同步给父容器
store.subscribe((mutation, state) => {
// 每次 mutation 之后调用
const nextState = cloneDeep(state)
// 这一步不是特别严谨,因为特殊的数据类型,比如 Date,Function,即便是不同,但是也会被 stringify 解析为一样的,可以使用 lodash 的深比较 isEqual,但是比较浪费性能,看项目取舍
if(JSON.stringify(nextState) !== JSON.stringify(prevState)) {
prevState = nextState
// 微应用中store变更后,将状态更新到主应用
props.setGlobalState &&
props.setGlobalState({...state.store})
}
})
}
const storeInstance = createStore({
...initStore,
plugins: [QiankunDataSharePlugin]
})
// 主应用状态变化后,同步到微应用
props.onGlobalStateChange &&
props.onGlobalStateChange(
(state, prev) => {
storeInstance.commit('initStore', state)
console.log('vue3-app onGlobalStateChange', state, prev)
}, true
)
return storeInstance
}
export default initStore;
// main.js
let instance = null;
// 子应用挂载的时候去实例化 vue app 和挂载全局方法
export async function mount(props) {
render(props);
instance.config.globalProperties.$onGlobalStateChange = props.onGlobalStateChange;
instance.config.globalProperties.$setGlobalState = props.setGlobalState;
}
// 假如是乾坤应用,执行
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
// 重点是 store(props),传入 props 去获取 onGlobalStateChange 和 setGlobalState 方法
function render(props) {
const { container } = props;
instance = createApp(App);
instance.use(store(props)).mount(container ? container.querySelector('#app') : '#app');
}
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END