UNPKG

mini-stores

Version:

小程序多状态管理 - 解决跨页面跨组件间通信,简洁小巧高性能,支持微信、支付宝、钉钉、百度、字节、QQ等小程序

269 lines (268 loc) 9.56 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Store = void 0; function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } var TYPE_ARRAY = '[object Array]'; var TYPE_OBJECT = '[object Object]'; var TYPE_FUNCTION = '[object Function]'; function getType(obj) { return Object.prototype.toString.call(obj); } function deepCopy(data) { var type = getType(data); if (type === TYPE_OBJECT) { var obj = {}; Object.keys(data).forEach(function (key) { return obj[key] = deepCopy(data[key]); }); return obj; } if (type === TYPE_ARRAY) { return data.map(deepCopy); } return data; } function getNowPage() { var pages = getCurrentPages(); return pages[pages.length - 1]; } function setState(vm, data) { vm._new_data = vm._new_data || {}; Object.assign(vm._new_data, data); return new Promise(function (resolve) { Promise.resolve().then(function () { if (vm._new_data) { var diffState = getDiffState(vm._new_data, vm.data); vm._new_data = null; vm.setData(diffState, resolve); } else { resolve(); } }); }); } function getDiffState(state, preState) { var newState = {}; stateDiff(deepCopy(state), preState, '', newState); return newState; } function addDiffState(newState, key, val) { if (key !== '') newState[key] = val; } function stateDiff(state, preState, path, newState) { if (state === preState) return; var stateType = getType(state); var preStateType = getType(preState); if (stateType === TYPE_OBJECT) { var stateKeys = Object.keys(state); var preStateKeys = Object.keys(preState || {}); var stateLen = stateKeys.length; var preStateLen = preStateKeys.length; if (path !== '') { if (preStateType !== TYPE_OBJECT || stateLen < preStateLen || stateLen === 0 || preStateLen === 0) { addDiffState(newState, path, state); return; } preStateKeys.forEach(function (key) { if (state[key] === undefined) { state[key] = null; if (!stateKeys.includes(key)) { stateKeys.push(key); } } }); } stateKeys.forEach(function (key) { var subPath = path === '' ? key : "".concat(path, ".").concat(key); stateDiff(state[key], preState[key], subPath, newState); }); return; } if (stateType === TYPE_ARRAY) { if (preStateType !== TYPE_ARRAY || state.length < preState.length || state.length === 0 || preState.length === 0) { addDiffState(newState, path, state); return; } preState.forEach(function (_, index) { if (state[index] === undefined) state[index] = null; }); state.forEach(function (item, index) { stateDiff(item, preState[index], "".concat(path, "[").concat(index, "]"), newState); }); return; } addDiffState(newState, path, state); } function getVmRoute(vm) { return vm.route; } function initRoute(vm) { return vm.route || vm.__route__; } function getValueByPaths(data, paths) { var value = data; paths.forEach(function (key) { var _value; value = (_value = value) === null || _value === void 0 ? void 0 : _value[key]; }); return value; } var Store = exports.Store = /*#__PURE__*/function () { function Store() { var _this = this; _classCallCheck(this, Store); _defineProperty(this, "__vms", []); _defineProperty(this, "__delayTimer", null); _defineProperty(this, "__updateTimer", null); _defineProperty(this, "__watchTimer", null); _defineProperty(this, "__watchMap", {}); _defineProperty(this, "data", {}); _defineProperty(this, "watch", { on: function on(key, callback, vm) { if (!key || typeof callback !== 'function') { console.warn("\u8BF7\u4F20\u5165\u6B63\u786E\u53C2\u6570\uFF0C\u5982store.watch.on('key', () => {})"); return; } key = String(key); if (!_this.__watchMap[key]) { var paths = String(key).split('.').filter(function (f) { return !!f; }); if (!paths.length) return; _this.__watchMap[key] = { paths: paths, value: getValueByPaths(_this.data, paths), callbacks: [] }; } _this.__watchMap[key].callbacks.push({ vm: vm, callback: callback }); }, off: function off(key, callback) { key = String(key); if (!_this.__watchMap[key]) return; _this.__watchMap[key].callbacks = _this.__watchMap[key].callbacks.filter(function (f) { return f.callback !== callback; }); } }); _defineProperty(this, "__proxyCache", new WeakMap()); _defineProperty(this, "__createProxy", function (obj) { if (_this.__proxyCache.has(obj)) { return _this.__proxyCache.get(obj); } var proxy = new Proxy(obj, { get: function get(target, propKey, receiver) { var value = Reflect.get(target, propKey, receiver); var type = getType(value); if (type === TYPE_FUNCTION) { return value.call(_this.data); } if (type === TYPE_OBJECT) { return _this.__createProxy(value); } return value; }, set: function set(target, propKey, value, receiver) { clearTimeout(_this.__updateTimer); _this.__updateTimer = setTimeout(function () { return _this.__update(); }); return Reflect.set(target, propKey, value, receiver); } }); _this.__proxyCache.set(obj, proxy); return proxy; }); setTimeout(function () { _this.data = _this.__createProxy(_this.data); }, 0); } return _createClass(Store, [{ key: "bind", value: function bind(vm, key) { if (!key) { console.error("\u8BF7\u8BBE\u7F6Estore\u5728\u5F53\u524D\u7EC4\u4EF6\u5B9E\u4F8Bdata\u4E2D\u7684key\uFF0C\u5982store.bind(this, '$store')"); return; } vm.data = vm.data || {}; vm.data[key] = null; setState(vm, _defineProperty({}, key, this.data)); if (!this.__vms.some(function (f) { return f.vm === vm && f.key === key; })) { this.__vms.push({ vm: vm, key: key }); var rootVm = vm.$page || vm.pageinstance || getNowPage() || {}; vm.route = initRoute(vm) || initRoute(rootVm); } } }, { key: "unbind", value: function unbind(vm) { var _this2 = this; this.__vms = this.__vms.filter(function (f) { return f.vm !== vm; }); Object.keys(this.__watchMap).forEach(function (key) { _this2.__watchMap[key].callbacks = _this2.__watchMap[key].callbacks.filter(function (f) { return f.vm !== vm; }); }); } }, { key: "__update", value: function __update() { var _this3 = this; var nowVm = getNowPage(); var nowVmRoute = getVmRoute(nowVm); var delayVms = []; this.__vms.forEach(function (f) { var vmRoute = getVmRoute(f.vm); if (nowVmRoute === vmRoute) { setState(f.vm, _defineProperty({}, f.key, _this3.data)); } else { delayVms.push(f); } }); clearTimeout(this.__watchTimer); this.__watchTimer = setTimeout(function () { Object.keys(_this3.__watchMap).forEach(function (key) { var item = _this3.__watchMap[key]; var value = getValueByPaths(_this3.data, item.paths); var oldValue = item.value; if (oldValue !== value) { item.value = value; item.callbacks.forEach(function (f) { return f.callback(value, oldValue); }); } }); }, 0); if (!delayVms.length) return; clearTimeout(this.__delayTimer); this.__delayTimer = setTimeout(function () { delayVms.forEach(function (f) { return setState(f.vm, _defineProperty({}, f.key, _this3.data)); }); }, 360); } }, { key: "update", value: function update() { this.__update(); } }]); }();