我們知道,object.defineproperty不能檢測陣列的操作,因此需要攔截陣列的操作(push, unshift, splice等)並重寫他們,使之可以對新操作的資料進行檢測。
攔截陣列方法的思路:
快取陣列的操作方法,直接快取array.prototype就行
使用乙個**陣列,重寫**陣列的操作方法,**陣列的原型指向array.prototype
例項繼承**陣列
**實現
上述**,通過重寫arraymethods上的陣列操作方法,實現了在運算元組時,通知依賴更新。const arrayproto = array.prototype // step1
const arraymethods = object.
create
(arrayproto)
// step2
const methodstopath =
['push'
,'pop'
,'shift'
]methodstopath.
foreach
(function
(method))}
)
你以為這就完成了嗎? 不。還需要補充一點。
運算元組之後,陣列發生了什麼變化?
答: 陣列增加了元素
,刪除了元素
,變更了元素順序
(還有可能是元素被替換了,不過替換可以理解為先刪除後增加兩個動作)。
重點來看增加了元素
, 即push
,unshift
,splice
這三個方法,為什麼要重點關注呢? 因為新增加的元素是非響應式的,所以需要獲取這些元素,並將其變為響應式資料才行。
// 上面所省略的那部分**
...const ob = value.__proto__
let inserted // 用來獲取新增的元素
switch
(method)
if(inserted) ob.
observearray
(inserted)
//notify change
ob.dep.
notify()
...
splice
()方法向/從陣列中 新增/刪除專案,然後返回被刪除的專案,該方法會改變原始陣列
arrayobj.
splice
(index, homany, item1,
..., itemx)
1. index: 必需,新增或刪除專案的位置索引
2. howmany: 必需,要刪除的專案數量,如設定為0,表示不刪除
3. item1,
...itemx: 可選,向陣列中新增的新專案
// 上述 inserted = args.slice(2) 就是取 第三項之後的所有項
vue中是如何監聽陣列變化?
我們知道通過object.defineproperty 劫持陣列為其設定getter和setter後,呼叫的陣列的push splice pop等方法改變陣列元素時並不會觸發陣列的setter,這就會造成使用上述方法改變陣列後,頁面上並不能及時體現這些變化,也就是陣列資料變化不是響應式的 對上述不了...
vue如何監聽陣列變化?
vue.js觀察陣列變化主要通過以下7個方法 push pop shift unshift splice sort reverse 怎麼實現?通過對data資料中陣列的這7個方法進行重新包裝 注意只是data資料中的陣列 為什麼不直接對array.prototype的原型方法進行重新包裝?因為不應該...
Vue不能檢測陣列和物件的變化
上班第一天沒事做寫篇部落格。前段時間出去面試了下,vue不能檢測陣列和物件的變化 這個問題很高頻提起,今天來聊下這個問題 先看官網文件說明 情況一 新增的值不會觸發響應 刪除同理 情況二 原有的值改變會觸發響應 情況三 vue提供的方法 set可以觸發響應 以上3個例子總結了物件增 刪,模板沒有響應...