辅助功能
微前端环境变量
在执行子应用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__
},
}
}
主子应用通信
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>