@hsui/micro-app
Version:
Hundsun micro-app framework
102 lines (100 loc) • 3.6 kB
JavaScript
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
/**
* 模仿 qiankun 实现的状态管理
* - store 在初始化后只能部署一个监听回调,多次部署会被覆盖掉
* - store 在更新的时候只有初始化时指定的状态值才会被更改,并触发监听
* - store 部署的监听回调在应用 unmount 时会被自动移除
*/
import { cloneDeep } from 'lodash';
var globalState = {};
var deps = {};
// 触发全局监听
function emitGlobal(state, prevState) {
Object.keys(deps).forEach(function (id) {
if (deps[id] instanceof Function) {
deps[id](cloneDeep(state), cloneDeep(prevState));
}
});
}
export function initGlobalState() {
var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
if (state === globalState) {
console.warn('[hui] state has not changed!');
} else {
var prevGlobalState = cloneDeep(globalState);
globalState = cloneDeep(state);
emitGlobal(globalState, prevGlobalState);
}
return getMicroAppStateActions("global-".concat(+new Date()), true);
}
export function getMicroAppStateActions(id, isMaster) {
return {
/**
* onGlobalStateChange 全局依赖监听
*
* 收集 setState 时所需要触发的依赖
*
* 限制条件:每个子应用只有一个激活状态的全局监听,新监听覆盖旧监听,若只是监听部分属性,请使用 onGlobalStateChange
*
* 这么设计是为了减少全局监听滥用导致的内存爆炸
*
* 依赖数据结构为:
* {
* {id}: callback
* }
*
* @param callback
* @param fireImmediately
*/
onGlobalStateChange: function onGlobalStateChange(callback, fireImmediately) {
if (!(callback instanceof Function)) {
console.error('[hui] callback must be function!');
return;
}
if (deps[id]) {
console.warn("[hui] '".concat(id, "' global listener already exists before this, new listener will overwrite it."));
}
deps[id] = callback;
if (fireImmediately) {
var cloneState = cloneDeep(globalState);
callback(cloneState, cloneState);
}
},
/**
* setGlobalState 更新 store 数据
*
* 1. 对输入 state 的第一层属性做校验,只有初始化时声明过的第一层(bucket)属性才会被更改
* 2. 修改 store 并触发全局监听
*
* @param state
*/
setGlobalState: function setGlobalState() {
var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
if (state === globalState) {
console.warn('[hui] state has not changed!');
return false;
}
var changeKeys = [];
var prevGlobalState = cloneDeep(globalState);
globalState = cloneDeep(Object.keys(state).reduce(function (_globalState, changeKey) {
if (isMaster || _globalState.hasOwnProperty(changeKey)) {
changeKeys.push(changeKey);
return Object.assign(_globalState, _defineProperty({}, changeKey, state[changeKey]));
}
console.warn("[hui] '".concat(changeKey, "' not declared when init state\uFF01"));
return _globalState;
}, globalState));
if (changeKeys.length === 0) {
console.warn('[hui] state has not changed!');
return false;
}
emitGlobal(globalState, prevGlobalState);
return true;
},
// 注销该应用下的依赖
offGlobalStateChange: function offGlobalStateChange() {
delete deps[id];
return true;
}
};
}