mini-program-event-store
Version:
A small responsive system suitable for handling data responsive issues in mini program development
120 lines (108 loc) • 3.7 kB
JavaScript
import { isObject } from "./utils.js";
import { EventBus } from "./index.js";
class EventStore {
constructor(options) {
if (!isObject(options.state)) {
throw new TypeError("the state must be object type");
}
if (options.actions && isObject(options.actions)) {
const values = Object.values(options.actions);
for (const value of values) {
if (typeof value !== "function") {
throw new TypeError("the value of actions must be a function");
}
}
this.actions = options.actions;
}
this.state = options.state;
this._observe(options.state);
this.event = new EventBus();
this.eventV2 = new EventBus();
}
_observe(state) {
const _this = this;
Object.keys(state).forEach((key) => {
let _value = state[key];
Object.defineProperty(state, key, {
get: function () {
return _value;
},
set: function (newValue) {
if (_value === newValue) return;
/**
* 这里没有赋值(state[key] = "newValue"),为什么对应的value值是最新的?
* get 返回的是_value
*/
_value = newValue;
// 用于 onState
_this.event.emit(key, _value);
// 用于 onStates
_this.eventV2.emit(key, { [key]: _value });
},
});
});
}
// 监听 stateKey 的变化
onState(stateKey, stateCallback) {
const keys = Object.keys(this.state);
if (keys.indexOf(stateKey) === -1) {
throw new Error("the state does not contain your key");
}
// 收集依赖
this.event.on(stateKey, stateCallback);
// callback
if (typeof stateCallback !== "function") {
throw new TypeError("the event callback must be function type");
}
// 立即执行回调函数,返回stateKey的值。后面stateKey变化了,执行bus里面的回调就行了
const value = this.state[stateKey];
stateCallback.apply(this.state, [value]);
}
// ["name", "age"] callback1
// ["name", "height"] callback2
// 监听 多个stateKey 的变化
onStates(statekeys, stateCallback) {
const keys = Object.keys(this.state);
const value = {};
for (const theKey of statekeys) {
if (keys.indexOf(theKey) === -1) {
throw new Error("the state does not contain your key");
}
this.eventV2.on(theKey, stateCallback);
value[theKey] = this.state[theKey];
}
stateCallback.apply(this.state, [value]);
}
offStates(stateKeys, stateCallback) {
const keys = Object.keys(this.state);
stateKeys.forEach((theKey) => {
if (keys.indexOf(theKey) === -1) {
throw new Error("the state does not contain your key");
}
this.eventV2.off(theKey, stateCallback);
});
}
offState(stateKey, stateCallback) {
const keys = Object.keys(this.state);
if (keys.indexOf(stateKey) === -1) {
throw new Error("the state does not contain your key");
}
this.event.off(stateKey, stateCallback);
}
// 更改 stateKey 的值
setState(stateKey, stateValue) {
// 触发set -> emit
this.state[stateKey] = stateValue;
}
dispatch(actionName, ...args) {
if (typeof actionName !== "string") {
throw new TypeError("the action name must be string type");
}
if (Object.keys(this.actions).indexOf(actionName) === -1) {
throw new Error("this action name does not exist, please check it");
}
const actionFn = this.actions[actionName];
actionFn.apply(this, [this.state, ...args]);
}
}
export { EventStore };