Skip to content

辅助功能

微前端环境变量

在执行子应用js前,往沙箱proxy全局对象添加环境变量; 此时全局的window对象是访问不到这个属性的,隔离性很强

js
export default function getAddOn(global) {
  return {
    async beforeLoad() {
      // 挂载前进行环境变量设置【挂载在proxy对象上】
      global.__POWERED_BY_QIANKUN__ = true
    },
    async beforeUnmount() {
      // 卸载时移除 微前端 环境变量
      delete global.__POWERED_BY_QIANKUN__
    },
  }
}

主子应用通信

image

js
let deps = {}
let state = null

// 触发 onGlobalStateChange 的回调
function emitGlobal(state, prevState) {
  Object.keys(deps).forEach((id: string) => {
    if (deps[id] instanceof Function) {
      deps[id](cloneDeep(state), cloneDeep(prevState));
    }
  });
}

// 初始化状态
function initGlobalState(state = {}) {
  // 克隆一份旧props
  const prevGlobalState = cloneDeep(globalState);
  // 保存新props
  globalState = cloneDeep(state);
  // 触发监听回调,传入新旧props
  emitGlobal(globalState, prevGlobalState);
  return getMicroAppStateActions(`global-${+new Date()}`, true); // 返回若干 API
}

 function getMicroAppStateActions(id, isMaster) {
  return {
    // 保存回调
    onGlobalStateChange(callback, fireImmediately) {
      deps[id] = callback;
    },
    /**
     * 1. 对输入 state 的第一层属性做校验,只有初始化时声明过的第一层(bucket)属性才会被更改
     * 2. 修改 store 并触发全局监听
     */
    setGlobalState(state = {}) {
      const changeKeys = [];
      // 旧值
      const prevGlobalState = cloneDeep(globalState);
      // 新值
      globalState = cloneDeep(
        // 遍历更改对象的key
        Object.keys(state).reduce((_globalState, changeKey) => {
          if (isMaster || _globalState.hasOwnProperty(changeKey)) {
            // 将每个key值放入 changeKeys
            changeKeys.push(changeKey);
            // 新值覆盖旧值
            return Object.assign(_globalState, { [changeKey]: state[changeKey] });
          }
          return _globalState;
        }, globalState),
      );
      // 触发事件
      emitGlobal(globalState, prevGlobalState);
      return true;
    },

    // 删除state
    offGlobalStateChange() {
      delete deps[id];
      return true;
    },
  };
}

原生自定义事件

CustomEvent & dispatchEvent & addEventListener

html
<html lang="en">
<body>
  <iframe src="./自定义事件-iframe.html" frameborder="0"></iframe>
  自定义事件API:customEvent
  <script>
    // 自定义事件:test
    const test = new CustomEvent('test', {
      detail: {
        p1: 1,
      }
    })
    // 监听自定义事件[]
    window.addEventListener('test', (eventObj) => {
      console.log('params: ', eventObj.detail) //  { p1: 1 }
    })
    // 触发自定义事件【dispatchEvent为DOM对象上都存在的内置方法】
    setTimeout(() => {
      window.dispatchEvent(test) // 传入事件对象,不接受字符串作为参数
    }, 3000)
  </script>
</body>
</html>