Vue 原理學習總結

Vue 如何實現響應式原理

Vue 將MVVM做爲數據綁定的入口。
幾個Vue源碼關鍵核心概念:

  • Observer 數據的觀察者,監聽自己的model數據變化
  • Complie 解析編譯模板指令
  • Watcher 數據訂閱者,是Observer 與 Complie 之間通信的橋樑(用來訂閱變化時執行相應操作的)。

進一步分析
雙向綁定流程:

Observer --data update–> Dep --notify通知–> Watcher --update–> View
-------------------------------Dep----<–subscribe訂閱—Watcher--------------------
在這裏插入圖片描述

Dep 是Observer 和 Watcher 之間的橋樑, Observer 觀察到數據變化則告知 Dep, Dep會向收集到的Watcher 訂閱者們(Dep 內會有一個數組用來收集依賴的訂閱者),發送數據改變的通知,收到通知後進行View更新。*

一個簡單的實現Demo實例:

class Vue{
   constructor (options) {
       this.$options = options
       this._data = options.data
       observer(options.data, this._update.bind(this))
       this._update()
   }
   _update() {
       this.$options.render()
    }
}
function observer(obj, cb) {
   Object.keys(obj).forEach(key => {
       defineReactive(obj, key, obj[key], cb)
   })
}
function defineReactive(obj, key, val, cb) {
   Object.defineProperty(obj, key, {
       enumerable: true,
       configurable: true,
       get: ()=> {
           console.log(`訪問了: ${key}`)
           return val
       },
       set: newVal => {
           if(newValue === val) 
              return
           console.log(`設置了: ${key}`)
           val = newVal
           cb()
       }
   })
}

var vm = new Vue({
   el: '#app',
   data: {
       text: "vm data attr"
   },
   render(){
      console.log('runder function run.....')
   }
})

vue 如何通過Dep 避免渲染無關值更新導致的渲染問題:

vue 會在Render 函數中,收集本次渲染相關的值,並處理相關值爲響應式。 所以,與渲染無關的值,並不會觸發get, 也就不會在依賴收集器中添加到監聽。 所以渲染無關的值,即使調用set賦值, notify中的subs也是空的。 因此不會觸發渲染。
注: 這裏“依賴收集器” 並非官網定義的名詞。 只是個人理解起名。

總結:

  • vuedata 初始化爲一個Observer 並將對象中的每個值,重寫其get, set, data中的每個key, 都有一個獨立的依賴收集器;
  • get中,向依賴收集器添加了監聽;
  • 在mount 時, 實例了一個Watcher, 將收集器的目標指向了當前Watcher
  • data值發生變更時,觸發set, 觸發了依賴收集器中的所有監聽的更新, 從而觸發Watcher.update
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章