let obj = {}; let obj1 = { name: 'xiaoyu', age: 18, } //实现origin对象代理target对象 function proxyData(origin,target){ Object.keys(target).forEach(function(key){ Object.defineProperty(origin,key,{//定义origin对象的key属性 enumerable: false, configurable: true, get: function getter(){ return target[key];//origin[key] = target[key]; }, set: function setter(newValue){ target[key] = newValue; } }) }) }
vue中的数据代理也是通过这种方式来实现的。
function MVVM(options) { this.$options = options || {}; var data = this._data = this.$options.data; var _this = this;//当前实例vm // 数据代理 // 实现 vm._data.xxx -> vm.xxx Object.keys(data).forEach(function(key) { _this._proxyData(key); }); observe(data, this); this.$compile = new Compile(options.el || document.body, this); } MVVM.prototype = { _proxyData: function(key) { var _this = this; if (typeof key == 'object' && !(key instanceof Array)){//这里只实现了对对象的监听,没有实现数组的 this._proxyData(key); } Object.defineProperty(_this, key, { configurable: false, enumerable: true, get: function proxyGetter() { return _this._data[key]; }, set: function proxySetter(newVal) { _this._data[key] = newVal; } }); }, };
实现Observe
1、双向数据绑定
数据变动 ---> 视图更新
视图更新 ---> 数据变动
要想实现当数据变动时视图更新,首先要做的就是如何知道数据变动了,可以通过Object.defineProperty()函数监听data对象里的数据,当数据变动了就会触发set()方法。所以我们需要实现一个数据监听器Observe,来对数据对象中的所有属性进行监听,当某一属性数据发生变化时,拿到最新的数据通知绑定了该属性的订阅器,订阅器再执行相应的数据更新回调函数,从而实现视图的刷新。
当设置this.name = 'hello vue'时,就会执行set函数,通知订阅器里的订阅者执行相应的回调函数,实现数据变动,对应视图更新。
function observe(data){ if (typeof data != 'object') { return ; } return new Observe(data); } function Observe(data){ this.data = data; this.walk(data); } Observe.prototype = { walk: function(data){ let _this = this; for (key in data) { if (data.hasOwnProperty(key)){ let value = data[key]; if (typeof value == 'object'){ observe(value); } _this.defineReactive(data,key,data[key]); } } }, defineReactive: function(data,key,value){ Object.defineProperty(data,key,{ enumerable: true,//可枚举 configurable: false,//不能再define get: function(){ console.log('你访问了' + key);return value; }, set: function(newValue){ console.log('你设置了' + key); if (newValue == value) return; value = newValue; observe(newValue);//监听新设置的值 } }) } }
内容版权声明:除非注明,否则皆为本站原创文章。