一文了解vue中watcher資料雙向繫結原理(附程式碼)
之前的文章《》中,給大家瞭解了vue中observer資料雙向繫結原理。下面本篇文章給大家瞭解vue中watcher資料雙向繫結原理,一定的參考價值,有需要的朋友可以參考一下。
vue
資料雙向繫結原理,和簡單的實現,本文將實現mvvm
的watcher
1)
2)
3)
vue
資料雙向繫結原理,和簡單的實現,本文將實現mvvm
的Watcher
上面的步驟已經實現了監聽器,和訂閱器,當屬性發生改變,發出通知,那麼這個通知是通知誰呢,肯定是訂閱者watcher
.Watcher
訂閱者作為Observer
和Compile
之間通訊的橋樑,主要做的事情是:
1、在自身例項化時往屬性訂閱器(dep
)裡面新增自己
2、自身必須有一個update()
方法
3、待屬性變動dep.notice()
通知時,能呼叫自身的update()
方法,並觸發Compile
中繫結的回撥,則釋放自己。
// Watcher function Watcher(vm, exp, cb) { this.cb = cb; this.$vm = vm; this.exp = exp; // 此處為了觸發屬性的getter,從而在dep新增自己,結合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); // 執行Compile中繫結的回撥,更新檢視 } }, get: function () { Dep.target = this; // 將當前訂閱者指向自己, 快取 var value = this.$vm[this.exp]; // 強制觸發監聽的getter,新增自己到屬性訂閱器中 Dep.target = null; // 新增完畢,重置釋放 return value; }, };
訂閱者要快取自己,並且告訴監聽器,要把我加到訂閱器裡面去。所以還要改造下監聽器
function defineReactive(data, key, val) { var dep = new Dep() observe(val); // 監聽子屬性 Object.defineProperty(data, key, { .... get: function() { // 由於需要在閉包內新增watcher,所以可以在Dep定義一個全域性target屬性,暫存watcher, 新增完移除 Dep.target && dep.addDep(Dep.target); return val; }, .... }); }
例項化Watcher
的時候,呼叫get()
方法,透過Dep.target=watcherInstance
標記訂閱者是當前watcher
例項,強行觸發屬性定義的getter
方法,getter
方法執行的時候,就會在屬性的訂閱器dep
新增當前watcher
例項,從而在屬性值有變化的時候watcherInstance
就能收到更新通知。
實現MVVM
到這兒先將監聽器Observer
和監聽者Watcher
連起來,先模擬一些資料,實現簡單的資料繫結
<div id="name"></div> <script> function Vue(data, el, exp) { this.data = data; observe(data); el.innerHTML = this.data[exp]; // 初始化模板資料的值 new Watcher(this, exp, function (value) { el.innerHTML = value; }); return this; } var ele = document.querySelector("#name"); var vue = new Vue( { name: "hello world", }, ele, "name" ); setInterval(function () { vue.data.name = "chuchur " + new Date() * 1; }, 1000); </script>
這可以看到div
的和內容初始為hello world
,每隔一秒之後變換為chuchur
加時間戳,雖然是實現了,但是與想象的還差很多。是vue.name
不是vue.data.name
,所以這裡需要給Vue
例項新增一個屬性代理的方法,使訪問vm
的屬性代理為訪問vm.data
的屬性,改造後的程式碼如下:
function Vue(options) { this.$options = options || {}; this.data = this.$options.data; // 屬性代理,實現 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]; // 初始化模板資料的值 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
,直接改版模板的資料了,下一步就要實現解析器Complie
[完]
推薦學習:
以上就是一文了解vue中watcher資料雙向繫結原理(附程式碼)的詳細內容,更多請關注php中文網其它相關文章!
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3137/viewspace-2827395/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- vue中的雙向資料繫結原理Vue
- Vue資料雙向繫結原理Vue
- vue雙向資料繫結原理Vue
- Vue 雙向資料繫結原理分析Vue
- vue雙向繫結原理Vue
- vue資料雙向繫結的實現原理Vue
- Vue 中雙向繫結 Vs 單向資料流Vue
- vue雙向繫結的原理及實現雙向繫結MVVM原始碼分析VueMVVM原始碼
- [JS] 資料雙向繫結原理JS
- 原始碼分析:Vue的雙向資料繫結原始碼Vue
- 雙向資料繫結實現原理
- vue.js雙向資料繫結Vue.js
- 淺析vue的雙向資料繫結Vue
- Vue props 雙向資料繫結方法Vue
- 剖析Vue原理&實現雙向繫結MVVMVueMVVM
- 梳理vue雙向繫結的實現原理Vue
- Vue雙向繫結原理,教你一步一步實現雙向繫結Vue
- vue 雙向繫結(v-model 雙向繫結、.sync 雙向繫結、.sync 傳物件)Vue物件
- js 實現vue的雙向資料繫結JSVue
- Vue雙向繫結初探Vue
- vue-原始碼剖析-雙向繫結Vue原始碼
- 千鋒長沙前端培訓:Vue的雙向資料繫結原理前端Vue
- 從最簡單的資料劫持瞭解vue雙向繫結原理Vue
- Vue.js 3.x 雙向繫結原理Vue.js
- JS雙向資料繫結JS
- 基於vue實現的雙向資料繫結Vue
- Vue原始碼學習之雙向繫結Vue原始碼
- vue雙向繫結盲區Vue
- Vue雙向繫結實現Vue
- 揭密 Vue 的雙向繫結Vue
- Vue、MVVM、MVC、雙向繫結VueMVVMMVC
- 原生js雙向資料繫結JS
- 【阿不】深入ASP.NET資料繫結(中)—資料雙向繫結機理ASP.NET
- 從單向到雙向資料繫結
- 0 到 1 掌握:Vue 核心之資料雙向繫結Vue
- 手動簡單實現Vue雙向資料繫結Vue
- vue父子關係元件間的雙向資料繫結Vue元件
- MVVM雙向繫結機制的原理和程式碼實現MVVM