class MyProxy { constructor(that, watchData) { // watch函数回调集合 that.$_watchCallBack = {} // 绑定到指定对象 that.$watch = this.$watch; that.$emit = this.$emit; that.$get = this.$get; that.$Behavior = this.$_behavior(); that.$_proxy = this.$_proxy; that.$_remove = this.$_remove; that.$_autoRemove = this.$_autoRemove; // 设置监听对象 this._setWatchData(that, watchData); } /** * 设置被监听的对象 * @that {Object} this对象 * @watchData {object} 被监听的对象 */ _setWatchData(that, watchData) { that.$watchData = watchData || {} } /** * 设置代理 * @obj {Object} 将要代理的对象 * @callbackArray {Array} 回调函数集合 * */ $_proxy(key, value) { const obj = this.$watchData; let _oldValue = obj[key]; obj[key] = value; // 确认回调函数存在 循环执行回调数组的方法集合 this.$_watchCallBack[key] && this.$_watchCallBack[key].map(val => val && val.cb && val.cb.call(val.page, value, _oldValue)) } /** * 提交值 * @key {String} 提交的键值 * @value {any} 提交的值 * @callback {function} 执行之后完成回调 */ $emit(key, value, callback) { this.$_proxy(key, value); callback && callback() } /** * 获取值 * @key {String} 获取的键值 * @callback {function} 获取之后执行回调函数 */ $get(key, callback) { callback && callback(this.$watchData[key]); return this.$watchData[key] } /** * 添加watch方法 * @key {String} 要观察的键值 * @page {Object} 需监听的页面 * @callback {function} 需要执行的回调函数 * */ $watch(key, page, callback) { // 首先检测 $_watchCallBack 中对应的值是否存在 如果存在就推入方法 this.$_watchCallBack = Object.assign({}, this.$_watchCallBack, { [key]: this.$_watchCallBack[key] || [] }); // 判断页面是否存入过该方法 若存入过则更改回调方法 否则推入函数 let _index = this.$_watchCallBack[key].findIndex(val => val.name === page.__wxExparserNodeId__); if (_index === -1) { console.info(`${page.is} watch=>`, key) // 添加自动移除的方法 page = this.$_autoRemove(key, page) // 推入新的监听事件 this.$_watchCallBack[key].push({ name: page.__wxExparserNodeId__, page, cb: callback }) } else { // 存在则改写回调函数 this.$_watchCallBack[key][_index].cb = callback; } } /** * 移除监听事件 * @key {String} 需要移除监听的键值 * @page {Object} 需移除监听的页面 * @callback {function} 移除监听完成的回调函数 */ $_remove(key, page, callback) { // 获取索引 let _index = this.$_watchCallBack[key].findIndex(val => val.name === page.__wxExparserNodeId__); if (_index !== -1) { // 移除监听 let _item = this.$_watchCallBack[key].splice(_index, 1); if (_item) { // console.log('remove', key, page) // 确认函数存在 执行回调函数 callback && callback.call(page) } } } /** * 自动移除监听 * @key {String} 移除的键值 * @page {Object} 移除的页面 */ $_autoRemove(key, page) { // 如果是页面则重载onUnload 函数 if (page.route) { let _onUnload = page.onUnload; page.onUnload = () => { this.$_remove(key, page, () => { console.info(`${page.is} remove=>`, key) _onUnload() }) }; return page; } else { // 自定义组件暂时没想到什么办法 page.$$_watch = key; return page; } } /** * */ $_behavior() { return Behavior({ detached() { let key = this.$$_watch; wx.$_remove(this.$$_watch, this, () => { console.info(`${this.is} remove=>`, key) }) }, }) } } module.exports = { MyProxy: MyProxy }