本篇內(nèi)容主要講解“vue中watcher數(shù)據(jù)雙向綁定原理”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“vue中watcher數(shù)據(jù)雙向綁定原理”吧!
創(chuàng)新互聯(lián)專注骨干網(wǎng)絡(luò)服務(wù)器租用10余年,服務(wù)更有保障!服務(wù)器租用,德陽服務(wù)器托管 成都服務(wù)器租用,成都服務(wù)器托管,骨干網(wǎng)絡(luò)帶寬,享受低延遲,高速訪問。靈活、實現(xiàn)低成本的共享或公網(wǎng)數(shù)據(jù)中心高速帶寬的專屬高性能服務(wù)器。
vue
數(shù)據(jù)雙向綁定原理,和簡單的實現(xiàn),本文將實現(xiàn)mvvm
的watcher
1)vue數(shù)據(jù)雙向綁定原理-observer
2)vue數(shù)據(jù)雙向綁定原理-wather
3)vue數(shù)據(jù)雙向綁定原理-解析器Complie
vue
數(shù)據(jù)雙向綁定原理,和簡單的實現(xiàn),本文將實現(xiàn)mvvm
的Watcher
上面的步驟已經(jīng)實現(xiàn)了監(jiān)聽器,和訂閱器,當(dāng)屬性發(fā)生改變,發(fā)出通知,那么這個通知是通知誰呢,肯定是訂閱者watcher
.Watcher
訂閱者作為Observer
和Compile
之間通信的橋梁,主要做的事情是:
1、在自身實例化時往屬性訂閱器(dep
)里面添加自己
2、自身必須有一個update()
方法
3、待屬性變動dep.notice()
通知時,能調(diào)用自身的update()
方法,并觸發(fā)Compile
中綁定的回調(diào),則釋放自己。
// Watcher function Watcher(vm, exp, cb) { this.cb = cb; this.$vm = vm; this.exp = exp; // 此處為了觸發(fā)屬性的getter,從而在dep添加自己,結(jié)合Observer更易理解 this.value = this.get(); // 將自己添加到訂閱器的操作 } Watcher.prototype = { update: function () { this.run(); // 屬性值變化收到通知 }, run: function () { var value = this.get(); // 取到最新值 var oldVal = this.value; if (value !== oldVal) { this.value = value; this.cb.call(this.$vm, value, oldVal); // 執(zhí)行Compile中綁定的回調(diào),更新視圖 } }, get: function () { Dep.target = this; // 將當(dāng)前訂閱者指向自己, 緩存 var value = this.$vm[this.exp]; // 強制觸發(fā)監(jiān)聽的getter,添加自己到屬性訂閱器中 Dep.target = null; // 添加完畢,重置釋放 return value; }, };
訂閱者要緩存自己,并且告訴監(jiān)聽器,要把我加到訂閱器里面去。所以還要改造下監(jiān)聽器
function defineReactive(data, key, val) { var dep = new Dep() observe(val); // 監(jiān)聽子屬性 Object.defineProperty(data, key, { .... get: function() { // 由于需要在閉包內(nèi)添加watcher,所以可以在Dep定義一個全局target屬性,暫存watcher, 添加完移除 Dep.target && dep.addDep(Dep.target); return val; }, .... }); }
實例化Watcher
的時候,調(diào)用get()
方法,通過Dep.target=watcherInstance
標(biāo)記訂閱者是當(dāng)前watcher
實例,強行觸發(fā)屬性定義的getter
方法,getter
方法執(zhí)行的時候,就會在屬性的訂閱器dep
添加當(dāng)前watcher
實例,從而在屬性值有變化的時候watcherInstance
就能收到更新通知。
MVVM
到這兒先將監(jiān)聽器Observer
和監(jiān)聽者Watcher
連起來,先模擬一些數(shù)據(jù),實現(xiàn)簡單的數(shù)據(jù)綁定
這可以看到div
的和內(nèi)容初始為hello world
,每隔一秒之后變換為chuchur
加時間戳,雖然是實現(xiàn)了,但是與想象的還差很多。是vue.name
不是vue.data.name
,所以這里需要給Vue
實例添加一個屬性代理的方法,使訪問vm
的屬性代理為訪問vm.data
的屬性,改造后的代碼如下:
function Vue(options) { this.$options = options || {}; this.data = this.$options.data; // 屬性代理,實現(xiàn) vm.xxx -> vm.data.xxx var self = this; Object.keys(this.data).forEach(function(key) { self.proxy(key); // 綁定代理屬性 }); observe(this.data, this); el.innerHTML = this.data[exp]; // 初始化模板數(shù)據(jù)的值 new Watcher(this, exp, function(value) { el.innerHTML = value; }); return this; } Vue.prototype = { proxy: function(key) { var self = this; Object.defineProperty(this, key, { enumerable: false, configurable: true, get: function proxyGetter() { return self.data[key]; }, set: function proxySetter(newVal) { self.data[key] = newVal; } }); } }
然后就可以通過vue.name
,直接改版模板的數(shù)據(jù)了,下一步就要實現(xiàn)解析器Complie
到此,相信大家對“vue中watcher數(shù)據(jù)雙向綁定原理”有了更深的了解,不妨來實際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!