Communication between micro front-end qiankun applications

Communication principle:

  The qiankun framework provides a global object initGlobalState, which can be used to store globally shared data. Each sub-application can read and modify data through initGlobalState. initGlobalState will return three methods, namely:

  • setGlobalState: Set globalState - When setting a new value, a shallow check will be performed internally. If globalState is detected to have changed, a notification will be triggered and all observer functions will be notified.
  • onGlobalStateChange: Register an observer function - respond to changes in globalState and trigger the observer function when globalState changes.
  • offGlobalStateChange: Cancel the observer function - the instance no longer responds to globalState changes.

Official example:

Main application:

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();

Micro application:

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

Package:

The main application registers an instance of MicroAppStateActions and passes these actions to the micro application through 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;

Receive parameters in the micro application and register them in 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;

 Called in the micro application mount hook

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

  registerGlobalModule.globalRegister(store, props)

  render(props)
}

Guess you like

Origin blog.csdn.net/qq_55172460/article/details/131439911