Vue到底如何實現陣列響應式的?

2021-10-10 07:42:17 字數 1499 閱讀 6314

大家都知道,vue2.0 實現資料響應式主要是依賴object.defineproperty這個api,可實際上 defineproperty 不能監聽陣列變化,可是我們在vue中運算元組資料的時候,也能實現響應式更新,這是為什麼呢?

翻開  vue 原始碼  中的 src/core/observer/array.js 檔案,我們能看到,因為vue 的開發者對陣列改變資料的 7 個方法做了一些改動:

...

const arrayproto = array.prototype

export const arraymethods = object.create(arrayproto)

const methodstopatch = [

'push',

'pop',

'shift',

'unshift',

'splice',

'sort',

'reverse'

]/**

* intercept mutating methods and emit events

*/methodstopatch.foreach(function (method)

if (inserted) ob.observearray(inserted)

// notify change

ob.dep.notify()

return result

})})

接下來分步解析:

首先 取出 array的原型prototype 儲存在 arrayproto變數中,

const arrayproto = array.prototype
然後 在這個原型基礎之上create乙個新的物件 arraymethods

export const arraymethods = object.create(arrayproto)
接下來遍歷陣列這7個方法,在這些方法原有功能的基礎上,額外新增了通知 更新(ob.dep.notify())的操作

methodstopatch.foreach(function (method) )

})

先是正常呼叫當前方法

最重要的是,最後 dep.notify() 通知更新

...

ob.dep.notify()

return result

這期間,只能監聽陣列原有值的變化,而新增的 值 需要重新監聽起來,這就需要:

let inserted

switch (method)

// ob.observearray給新增的屬性新增監聽依賴

if (inserted) ob.observearray(inserted)

至此,在陣列原有方法的基礎上,增加了資料監聽依賴,以達到陣列變化時候的 響應式更新。 

vue如何實現 陣列 的響應式

上原始碼,加上自己的理解 拿到陣列的原型 const arrayproto array.prototype 以陣列的原型建立乙個自己的物件,建立乙個物件作為 這裡暴露出去後會在 別處 使用到,用於對陣列型別原型的改變,使其在呼叫push等方法時會經過下面defineproperty中定義的方法,ex...

VUE陣列響應式

例如 let array 1,2,3,4,5 array.foreach c,index function definereactive obj,key,val set newval 我們可以遍歷陣列,用陣列的索引作為 key,來給每一項打上getter setter。原因 如果你知道陣列的長度,理...

vue的響應式實現原理

vue2.0的雙向資料繫結主要實現方式就是 發布訂閱 資料劫持 這裡來手寫乙個實現過程,發布訂閱 資料劫持 訂閱器模型 let dep 為何不是陣列?深拷貝與淺拷貝,使用陣列需要key來進行查值 新增訂閱者 listen function key,fn 發布訊息 trigger function v...