簡單來說,依賴收集的過程是:
在元件init
的過程中,將data
中的屬性新增getter/setter
方法
在元件渲染過程中(render
函式執行時),每個元件例項內部會例項化乙個watcher
物件,data
中的屬性會被touch
,觸發getter
方法,記錄元件和屬性的對應關係
當屬性更新時,訪問setter
方法,會呼叫對應的wachter
重新計算,呼叫render
函式,導致關聯元件更新
在init
階段,data
中的屬性會被新增getter
和setter
方法,手段就是呼叫object.defineproperty
方法
function definereactive(obj: object, key: string, ...) ,
set: function reactivesetter(newval) })}
data
中的每個屬性都有乙個dep
物件,getter
中會呼叫dep.depend()
方法
vue物件在init
之後進入mount
階段,關鍵函式是mountcomponent
:
mountcomponent(vm: component, el: ? element, ...)
new watcher(vm, updatecomponent, ...)
...}
在元件渲染過程中,例項化了乙個watcher
物件,它有兩個引數,第乙個引數vm
就是當前元件例項,第二個引數updatecomponent
會呼叫vm._render
和vm._update
方法,主要目的就是更新頁面
在元件需要更新的時候,vm._render
目的是將vue物件渲染為虛擬dom``vm._update`目的是將虛擬dom建立或更新為真實dom
watcher
就會被呼叫,更新頁面
lass watcher
}
在watcher
的建構函式中,會呼叫exporfn
方法,這個exporfn
就是上面的updatecomponent
方法,進而呼叫vm._render
方法
在這個過程中,會訪問data
中的屬性的getter
(也就是touch
的過程),這是會呼叫上面提到的dep.depend()
方法
為了弄清dep.depend()
方法究竟做了什麼,在dep
物件的建構函式中看:
class dep
} notify()
}}
dep.depend()
實際上呼叫了dep.target.adddep(this)
,而在watcher
的建構函式中有這樣的**dep.target = this
,所以dep.target.adddep(this)
也就是呼叫了watcher
的adddep
方法
而watcher
中的adddep
方法簡化後:
class watcher
}class dep
}
watcher
將這個dep
儲存了下來,然後呼叫了dep的addsub
方法,將watcher
存了進去
我這樣理解,dep
記錄了所有依賴這個屬性的元件和元件的watcher例項,同樣,在watcher中也記錄了當前元件例項都使用了哪些屬性
經過這些步驟,dep.depend
的導致addsub方法被呼叫,將當前的watcher
記錄到了元件的dep
的subs
中
修改data
中已經雙向繫結後的屬性,會呼叫setter
方法,呼叫了dep.notify
方法
class dep
} notify()
}}
dep.notify
方法呼叫所有依賴這個屬性的元件的watcher例項,執行render
方法,更新頁面
render
-watche
r-元件
是一一對應的,data中的每個屬性都有對應的dep
例項
更詳細的細節:
由於在vue的init
過程中,對data
中的屬性執行了getter
和setter
轉化過程,如果是未初始化話新增的data
根屬性,則無法被追蹤:
var vm = new vue(
})// `vm.a` 是響應的
vm.b = 2
// `vm.b` 是非響應的
還有乙個問題:
var vm = new vue(
})vm.items[1] = 'x' // 不是響應性的
vm.items.length = 2 // 不是響應性的
items
是陣列,陣列的索引並不是屬性,很難用dep
去繫結,長度length
也沒有被處理,解決方法:
vm.items.splice(indexofitem, 1, newvalue)
vm.items.splice(newlength)
vue響應式布局 Vue 響應式原理
vue2 的資料偵測 在 src observer 目錄裡面,元件例項在初始化時,會呼叫 observe 函式處理 data function initdata vm observe 改寫了所有物件屬性的 getter setter 和陣列原型上的 7 個會改寫陣列方法,從而讓 data 變成可響應...
vue響應式原理
響應式系統是vue框架核心的部分,資料物件僅僅是普通的 js物件。當我們改變資料時,檢視也會被改變,本文就來 一下vue 的響應式原理。vue響應式的核心是使用了es5 新增的api object.defineproperty 因此vue不支援ie8 object.defineproperty的作用...
vue響應式原理
要了解響應式原理首先應該知道什麼是響應式 更改 vue的響應式原理是什麼 vue資料的雙向繫結是通過資料劫持結合發布訂閱模式,偵測到資料變化,然後通過object.defineproperty 物件對每個屬性的getter和setter進行劫持。當讀取 data 中的資料時自動呼叫 get 方法,當...