Vue提高17 Vue響應式原理

2021-09-02 15:01:09 字數 3687 閱讀 4939

簡單來說,依賴收集的過程是:

在元件init的過程中,將data中的屬性新增getter/setter方法

在元件渲染過程中(render函式執行時),每個元件例項內部會例項化乙個watcher物件,data中的屬性會被touch,觸發getter方法,記錄元件和屬性的對應關係

當屬性更新時,訪問setter方法,會呼叫對應的wachter重新計算,呼叫render函式,導致關聯元件更新

init階段,data中的屬性會被新增gettersetter方法,手段就是呼叫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._rendervm._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)也就是呼叫了watcheradddep方法

watcher中的adddep方法簡化後:

class watcher 

}class dep

}

watcher將這個dep儲存了下來,然後呼叫了dep的addsub方法,將watcher存了進去

我這樣理解,dep記錄了所有依賴這個屬性的元件和元件的watcher例項,同樣,在watcher中也記錄了當前元件例項都使用了哪些屬性

經過這些步驟,dep.depend的導致addsub方法被呼叫,將當前的watcher記錄到了元件的depsubs

修改data中已經雙向繫結後的屬性,會呼叫setter方法,呼叫了dep.notify方法

class dep 

} notify()

}}

dep.notify方法呼叫所有依賴這個屬性的元件的watcher例項,執行render方法,更新頁面

render-watcher-元件是一一對應的,data中的每個屬性都有對應的dep例項

更詳細的細節:

由於在vue的init過程中,對data中的屬性執行了gettersetter轉化過程,如果是未初始化話新增的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 方法,當...