We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
大家可能对 vue 使用 defineProperty 方法来实现底层双向绑定也很熟悉了,下面简单实现一下简单的监听一个对象和数组的变化
/** * 检测对象属性被更改 */ const ARRAY = 0; const OBJECT = 1; /** * 数组变异方法 * 这几个方法会改变原来数组 */ const arrayAugmentations = []; const aryMethods = [ 'push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse' ]; aryMethods.forEach(method => { let original = Array.prototype[method]; arrayAugmentations[method] = function() { let result = original.apply(this, arguments); console.log('🍺 我是数组我被设置了', result) return result; }; }); /** * 对象添加新属性 * @param {*} data * @param {*} type * */ const objectAugmentations = {}; Object.defineProperty(objectAugmentations, '$add', { value: function(key, value) { if (this.hasOwnProperty(key)) return; Object.defineProperty(this, key, { configurable: true, get: function() { console.log('💖 我被获取了 我的值是', value) return value }, set: function(val) { console.log('🐂 我被设置了 我设置的新值是', val) if (val === value) return value = val; return value } }); }, configurable: true, }); Object.defineProperty(objectAugmentations, '$delete', { value: function(key) { if (!this.hasOwnProperty(key)) return; console.log('⛰ 我被删除了', key) delete this[key]; }, configurable: true, writable: true }); function Observer(data, type) { if (!(this instanceof Observer)) throw Error('should be called by new') this.data = data; console.log(data, '===>'); if (type === ARRAY) { data.__proto__ = arrayAugmentations; // eslint-disable-line this.link(data); } else if (type === OBJECT) { data.__proto__ = objectAugmentations; // eslint-disable-line this.walk(data); } }; Observer.prototype.walk = function(data) { if (typeof data !== 'object') return; for(key in data) { if (data.hasOwnProperty(key)) { let value = data[key]; if (typeof value == 'object') { Observer.create(value) } this.convert(key, value); } } } Observer.prototype.link = function(items) { items.forEach((value) => { let ob = Observer.create(value); if (!ob) return; }); }; Observer.prototype.convert = function(key, value) { console.log(key) Object.defineProperty(this.data, key, { configurable: true, enumerable: true, get: function() { console.log('💖 我被获取了 我的值是', value) return value }, set: function(val) { console.log('🐂 我被设置了 我设置的新值是', val) if (val === value) return value = val; return value } }); } /** * 根据不同的数据类型,调用observer构造函数 * @param value {Any} 数据 * @returns {Observer} */ Observer.create = function(value) { if (Array.isArray(value)) { return new Observer(value, ARRAY); } else if (typeof value === 'object') { return new Observer(value, OBJECT); } }; let data = { a: 1, b: { c: { d: 3 } }, arr: [4, 5] } let app = Observer.create(data); console.log() console.log('====start==') console.log(data.a); data.a = 'aaa'; console.log(data.a) console.log() console.log(data.b.c.d); data.b.c.d = 'dddd'; console.log(data.b.c.d) console.log() console.log(data.arr); console.log() console.log(data.arr.push(100)) console.log(data.arr) console.log() console.log(app.data.$add('age', 25)) console.log(data.age) console.log(app.data.$delete('age')) console.log('====end==')
参考
The text was updated successfully, but these errors were encountered:
No branches or pull requests
监听一个对象和数组的变化
参考
The text was updated successfully, but these errors were encountered: