Vue 的數據響應式原理

 

一、理解Vue的設計思想

MVVM框架的三要素:數據響應式、模板引擎及其渲染

(1) 數據響應式:監聽數據變化並在視圖中更新

  • Object.defineProperty()
  • Proxy

(2) 模版引擎:提供描述視圖的模版語法

  • 插值:{{}}
  • 指令:v-bind,v-on,v-model,v-for,v-if

(3) 渲染:如何將模板轉換爲html

  • 模板 => vdom => dom

 

二、數據響應式原理

數據變更能夠響應在視圖中,就是數據響應式。vue2中利用 Object.defineProperty() 實現變更檢測。

 

 三、響應式原理實現

(1)代碼:

// TODO 定義一個對象響應式原理

function defineReactive(obj, key, val) {
  // TODO 1。處理辦法
  observe(val)
  Object.defineProperty(obj, key, {
    get() {
      console.log('Get方法:', val)
      return val
    },
    set(newVal) {
      if (val !== newVal) {
        val = newVal
        console.log('Set方法:', val)
        // update(val)
        // TODO 2。問題2處理:obj.ccc賦值時,會進入到set攔截器,判斷newval值爲對象,我們需要對覆蓋的這個對象做處理
        if(typeof newVal === 'object') {
          observe(newVal)
        }
      }
    }
  })
}

// 更新函數
function update(val) {
  document.getElementById('#app').innerHTML = val
}

// 處理對象的響應式,遍歷對象中的所有key,對其做響應式處理
function observe(obj) {
  if (typeof obj !== 'object' || obj == null) {
    return;
  }
  Object.keys(obj).forEach(key => {
    defineReactive(obj, key, obj[key])
  })
}
// TODO 3。處理新增的屬性,增加響應式
function set(obj, key, val) {
  defineReactive(obj, key, val)
}

var obj = {
  foo :'foo',
  boo: '123',
  ccc: {
    test: 'test',
    test2: 'test2'
  }
}
// 將obj 註冊爲響應式
observe(obj)

// TODO 1。obj.ccc 是一個對象,對象內部也要實現響應式處理
obj.ccc.test
// TODO 2。原本已經給最初賦值的 obj.ccc = {} 做了響應式的處理,但是下面又對他重新覆蓋,導致,覆蓋的內容不能響應
obj.ccc = {test:1}
obj.ccc.test
// TODO 3。新增一個對象,是沒實現響應式處理,要自己實現一個set 方法
// obj.dong = 'dong'
set(obj, 'dong', 'dong')
obj.dong

// 每一秒觸發一次對象的set,並更新視圖View
// setInterval(() => {
//   obj.foo = new Date().toLocaleTimeString()
// }, 1000)

 

(2)實現結果:

傳入的對象都實現了set 和 get 的監聽。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章