| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- class Watch {
- constructor(that, watchData) {
- // watch函数回调集合
- that.$_watchCallBack = {}
- // 绑定到指定对象
- that.$watch = this.$watch;
- that.$emit = this.$emit;
- that.$get = this.$get;
- that.$behavior = this.$behavior();
- that.$_watch = this.$_watch;
- that.$_remove = this.$_remove;
- that.$_autoRemove = this.$_autoRemove;
- // 设置监听对象
- this._setWatchData(that, watchData);
- }
- /**
- * 设置被监听的对象
- * @that {Object} this对象
- * @watchData {object} 被监听的对象
- */
- _setWatchData(that, watchData) {
- if (that && watchData) {
- that.$watchData = Object.assign({}, watchData)
- } else {
- throw new Error('请输入正确的初始值')
- }
- }
- /**
- * 设置监听
- * @obj {Object} 将要监听的对象
- * @callbackArray {Array} 回调函数集合
- *
- */
- $_watch(key, value, callback) {
- const obj = this.$watchData;
- let _oldValue = obj[key];
- obj[key] = value;
- // 确认回调函数存在 循环执行回调数组的方法集合
- if (typeof _oldValue === 'object' && typeof value === 'object') {
- this.$_watchCallBack[key] && this.$_watchCallBack[key].forEach(val => val && val.cb && val.cb.call(val.page, value, _oldValue))
- } else {
- // 两次相同的值不执行
- _oldValue !== value && this.$_watchCallBack[key] && this.$_watchCallBack[key].forEach(val => val && val.cb && val.cb.call(val.page, value, _oldValue))
- }
- callback && callback()
- }
- /**
- * 提交值
- * @key {String} 提交的键值
- * @value {any} 提交的值
- * @callback {function} 执行之后完成回调
- */
- $emit(key, value, callback) {
- // 不提交未设置字段 减少消耗
- if (!this.$watchData.hasOwnProperty(key)) {
- throw new Error('未设置此字段')
- }
- // 不可传值为function、null、undefined以及NaN
- if (typeof value === 'function' || typeof value === 'undefined' || value === null || Number.isNaN(value)) {
- throw new Error(`${key}-${value}为非法参数传值`)
- }
- this.$_watch(key, value, 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 {
- // 自定义组件使用behaviors移除 将监听字段赋值给$$_watch
- page.$$_watch = key;
- return page;
- }
- }
- /**
- * 组件Behavior方法 需自行引入组件的behaviors
- */
- $behavior() {
- return Behavior({
- detached() {
- let key = this.$$_watch;
- wx.$_remove(this.$$_watch, this, () => {
- console.info(`${this.is} remove=>`, key)
- })
- },
- })
- }
- }
- module.exports = {
- Watch: Watch
- }
|