天天看點

Vue的資料響應式原理

什麼是響應式

“響應式”,是指當資料改變後,Vue 會通知到使用該資料的代碼。例如,視圖渲染中使用了資料,資料改變後,視圖也會自動更新。

舉個簡單的例子,對于模闆:

<div id="root">{{ name }}</div>           

複制

建立一個 Vue 元件:

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

複制

代碼執行後,頁面上對應位置會顯示:luobo。

如果想改變顯示的名字,隻需要執行:

vm.name = 'tang'           

複制

這樣頁面上就會顯示修改後的名字了,并不需要去手動修改 DOM 更新資料。

響應式原理

Vue 的響應式原理是核心是通過 ES5 的保護對象的 Object.defindeProperty 中的通路器屬性中的 get 和 set 方法,data 中聲明的屬性都被添加了通路器屬性,當讀取 data 中的資料時自動調用 get 方法,當修改 data 中的資料時,自動調用 set 方法,檢測到資料的變化,會通知觀察者 Wacher,觀察者 Wacher自動觸發重新render 目前元件(子元件不會重新渲染),生成新的虛拟 DOM 樹,Vue 架構會周遊并對比新虛拟 DOM 樹和舊虛拟 DOM 樹中每個節點的差别,并記錄下來,最後,加載操作,将所有記錄的不同點,局部修改到真實 DOM 樹上。

Vue的資料響應式原理

響應式缺陷

vue不能監聽數組的變化

Object.defindProperty雖然能夠實作雙向綁定了,但是還是有缺點,隻能對對象的屬性進行資料劫持,是以會深度周遊整個對象,不管層級有多深,隻要數組中嵌套有對象,就能監聽到對象的資料變化無法監聽到數組的變化,Proxy就沒有這個問題,可以監聽整個對象的資料變化,是以用vue3.0會用Proxy代替definedProperty。

Vue不能檢測到對象屬性的添加或删除

受現代JS的限制(以及廢棄 Object.observe),Vue不能檢測到對象屬性的添加或删除,由于Vue會在初始化執行個體時對屬性執行 getter/setter轉化過程,是以屬性必須在data對象上存在才能讓Vue轉換它,這樣才能讓它是響應的。

var vm = new Vue({
  data:{
    a:1
  }
})
// `vm.a` 是響應的
vm.b = 2
// `vm.b` 是非響應的           

複制

Vue不允許在已經建立的執行個體上動态添加新的根級響應式屬性(root-level reactive property),然而它可以使用 Vue.set(object, key, value) 方法将響應屬性添加到嵌套的對象上。

Vue.set(vm.someObject, 'b', 2)           

複制

也可以使用 vm.$set 執行個體方法,這也是全局 Vue.set 方法的别名。

this.$set(this.someObject,'b',2)           

複制

有時想向已有對象上添加一些屬性,例如使用Object.assign()或 _.extend()方法來添加屬性。但是,添加到對象上的新屬性不會觸發更新。在這種情況下可以建立一個新的對象,讓它包含原對象的屬性和新的屬性。

// 代替 `Object.assign(this.someObject, { a: 1, b: 2 })`
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })           

複制

資料雙向綁定原理

Vue的資料響應式原理