Vue、AngularJS 雙向數據綁定解剖


數據與視圖的綁定與同步,最終體現在對數據的讀寫處理過程中,也就是 Object.defineProperty() 定義的數據 set、get 函數中。Vue 中對於的函數為 defineReactive。

function defineReactive(obj, key, value) {
    var dep = new Dep()
    Object.defineProperty(obj, key, {
        enumerable: true,
        configurable: true,
        get: function reactiveGetter() {
            if (Dep.target) {
                dep.depend()
            }
            return value
        },
        set: function reactiveSetter(newVal) {
            if (value === newVal) {
                return
            } else {
                value = newVal
                dep.notify()
            }
        }
    })
}

在對數據進行讀取時,如果當前有 Watcher(對數據的觀察者吧,watcher 會負責將獲取的新數據發送給視圖),那將該 Watcher 綁定到當前的數據上(dep.depend(),dep 關聯當前數據和所有的 watcher 的依賴關系),是一個檢查並記錄依賴的過程。而在對數據進行賦值時,如果數據發生改變,則通知所有的 watcher(借助 dep.notify())。這樣,即便是我們手動改變了數據,框架也能夠自動將數據同步到視圖。

 

Vue 和 AngularJS 中,都是通過在 HTML 中添加指令的方式,將視圖元素與數據的綁定關系進行聲明。例如:

<form id="test">
  <input type="text" v-model="name">
</form>

以上的 HTML 代碼表示該 input 元素與 name 數據進行綁定。在 JS 代碼中可以這樣進行初始化:

var vm = new Vue({
  el: '#test',
  data: {
    name: 'luobo'
  }
})

代碼正確執行后,頁面上 input 元素對應的位置會顯示上面代碼中給出的初始值:luobo。

 

由於雙向數據綁定已經建立,因此:

  • 執行 vm.name = 'mickey' 后,頁面上 input 也會更新為顯示: mickey
  • 在頁面文本框中修改內容為:tang,則通過vm.name 獲取的值為:"tang"

那么初始化的過程中,Vue 是如何識別出這種綁定關系的呢?

通過分析源碼,在初始化過程中(new Vue() 執行時),主要執行兩個步驟:

  • compile
  • link

compile 過程中,對於給定的目標元素進行解析,識別出所有綁定在元素(通過 el 屬性傳入)上的指令。
link 過程中,建立這些指令與對應數據(通過 data 屬性傳入初始值)的綁定關系,並以數據的初始值進行渲染。綁定關系建立后,就可以雙向同步數據了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM