微前端qiankun应用间的通信

通信原理:

  qiankun框架提供了一个全局对象initGlobalState,可以用来存储全局共享的数据。各个子应用可以通过initGlobalState读取和修改数据,initGlobalState会返回三个方法,分别是:

  • setGlobalState:设置 globalState - 设置新的值时,内部将执行 浅检查,如果检查到 globalState 发生改变则触发通知,通知到所有的 观察者 函数。
  • onGlobalStateChange:注册 观察者 函数 - 响应 globalState 变化,在 globalState 发生改变时触发该 观察者 函数。
  • offGlobalStateChange:取消 观察者 函数 - 该实例不再响应 globalState 变化。

官方示例:

主应用:

import { initGlobalState, MicroAppStateActions } from 'qiankun';

// 初始化 state
const actions: MicroAppStateActions = initGlobalState(state);

actions.onGlobalStateChange((state, prev) => {
  // state: 变更后的状态; prev 变更前的状态
  console.log(state, prev);
});
actions.setGlobalState(state);
actions.offGlobalStateChange();

微应用:

// 从生命周期 mount 中获取通信方法,使用方式和 master 一致
export function mount(props) {
  props.onGlobalStateChange((state, prev) => {
    // state: 变更后的状态; prev 变更前的状态
    console.log(state, prev);
  });
 
  props.setGlobalState(state);
}

封装:

主应用 注册 MicroAppStateActions 实例,将这个actions通过props穿给微应用 

import { initGlobalState } from 'qiankun';

// 父应用的初始state
const initialState = {
	user: {
		name: '张三',
	},
};

const actions = initGlobalState(initialState);

actions.onGlobalStateChange((newState, prev) => {
	// state: 变更后的状态; prev 变更前的状态
	console.log('main change', JSON.stringify(newState), JSON.stringify(prev));

	for (const key in newState) {
		initialState[key] = newState[key];
	}
});

// 定义一个获取state的方法下发到子应用
actions.getGlobalState = key => {
	// 有key,表示取globalState下的某个子级对象
	// 无key,表示取全部

	return key ? initialState[key] : initialState;
};

export default actions;

微应用 中接收参数,并将它注册到vuex里面


/**
 * 
 * @param {vuex实例} store 
 * @param {qiankun下发的props} props 
 */
function registerGlobalModule (store, props = {}) {

  if (!store || !store.hasModule) {
    return;
  }

  // 获取初始化的state
  const initState = props.getGlobalState && props.getGlobalState() || {
    user: {}
  };

  // 将父应用的数据存储到子应用中,命名空间固定为global
  if (!store.hasModule('global')) {
    const globalModule = {
      namespaced: true,
      state: initState,
      actions: {
        // 子应用改变state并通知父应用
        setGlobalState ({ commit }, payload) {
          commit('setGlobalState', payload);
        },
        // 初始化,只用于mount时同步父应用的数据
        initGlobalState ({ commit }, payload) {
          commit('setGlobalState', payload);
        },
      },
      mutations: {
        setGlobalState (state, payload) {
          // eslint-disable-next-line
          state = Object.assign(state, payload);
          // 通知父应用
          if (props.setGlobalState) {
            props.setGlobalState(state);
          }
        },
      },
    };
    store.registerModule('global', globalModule);
  } else {
    // 每次mount时,都同步一次父应用数据
    store.dispatch('global/initGlobalState', initState);
  }
};

export default registerGlobalModule;

 在微应用mount钩子中调用

export async function mount (props) {
  console.log('[vue] props from main framework', props)

  registerGlobalModule.globalRegister(store, props)

  render(props)
}

你可能感兴趣的:(前端,vue,qiankun)