摘要:依賴收集是在響應(yīng)式基礎(chǔ)上進(jìn)行的,不熟悉的同學(xué)可以先了解響應(yīng)式原理。定義一個(gè)依賴收集類。訂閱者,當(dāng)依賴收集的時(shí)候回到中,在修改中數(shù)據(jù)的時(shí)候會(huì)觸發(fā)的,從而回調(diào)渲染函數(shù)。
寫(xiě)在前面
因?yàn)閷?duì)Vue.js很感興趣,而且平時(shí)工作的技術(shù)棧也是Vue.js,這幾個(gè)月花了些時(shí)間研究學(xué)習(xí)了一下Vue.js源碼,并做了總結(jié)與輸出。
文章的原地址:https://github.com/answershuto/learnVue。
在學(xué)習(xí)過(guò)程中,為Vue加上了中文的注釋https://github.com/answershuto/learnVue/tree/master/vue-src,希望可以對(duì)其他想學(xué)習(xí)Vue源碼的小伙伴有所幫助。
可能會(huì)有理解存在偏差的地方,歡迎提issue指出,共同學(xué)習(xí),共同進(jìn)步。
依賴收集是在響應(yīng)式基礎(chǔ)上進(jìn)行的,不熟悉的同學(xué)可以先了解《響應(yīng)式原理》。
為什么要依賴收集先看下面這段代碼
new Vue({ template: `text1: {{text1}} text2: {{text2}}`, data: { text1: "text1", text2: "text2", text3: "text3" } });按照之前《響應(yīng)式原理》中的方法進(jìn)行綁定則會(huì)出現(xiàn)一個(gè)問(wèn)題——text3在實(shí)際模板中并沒(méi)有被用到,然而當(dāng)text3的數(shù)據(jù)被修改的時(shí)候(this.text3 = "test")的時(shí)候,同樣會(huì)觸發(fā)text3的setter導(dǎo)致重新執(zhí)行渲染,這顯然不正確。
先說(shuō)說(shuō)Dep當(dāng)對(duì)data上的對(duì)象進(jìn)行修改值的時(shí)候會(huì)觸發(fā)它的setter,那么取值的時(shí)候自然就會(huì)觸發(fā)getter事件,所以我們只要在最開(kāi)始進(jìn)行一次render,那么所有被渲染所依賴的data中的數(shù)據(jù)就會(huì)被getter收集到Dep的subs中去。在對(duì)data中的數(shù)據(jù)進(jìn)行修改的時(shí)候setter只會(huì)觸發(fā)Dep的subs的函數(shù)。
定義一個(gè)依賴收集類Dep。
class Dep () { constructor () { this.subs = []; } addSub (sub: Watcher) { this.subs.push(sub) } removeSub (sub: Watcher) { remove(this.subs, sub) } notify () { // stabilize the subscriber list first const subs = this.subs.slice() for (let i = 0, l = subs.length; i < l; i++) { subs[i].update() } } }Watcher訂閱者,當(dāng)依賴收集的時(shí)候回addSub到sub中,在修改data中數(shù)據(jù)的時(shí)候會(huì)觸發(fā)Watcher的notify,從而回調(diào)渲染函數(shù)。
class Watcher () { constructor (vm, expOrFn, cb, options) { this.cb = cb; this.vm = vm; /*在這里將觀察者本身賦值給全局的target,只有被target標(biāo)記過(guò)的才會(huì)進(jìn)行依賴收集*/ Dep.target = this; /*觸發(fā)渲染操作進(jìn)行依賴收集*/ this.cb.call(this.vm); } update () { this.cb.call(this.vm); } }開(kāi)始依賴收集class Vue { constructor(options) { this._data = options.data; observer(this._data, options.render); let watcher = new Watcher(this, ); } } function defineReactive (obj, key, val, cb) { /*在閉包內(nèi)存儲(chǔ)一個(gè)Dep對(duì)象*/ const dep = new Dep(); Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: ()=>{ if (Dep.target) { /*Watcher對(duì)象存在全局的Dep.target中*/ dep.addSub(Dep.target); } }, set:newVal=> { /*只有之前addSub中的函數(shù)才會(huì)觸發(fā)*/ dep.notify(); } }) } Dep.target = null;將觀察者Watcher實(shí)例賦值給全局的Dep.target,然后觸發(fā)render操作只有被Dep.target標(biāo)記過(guò)的才會(huì)進(jìn)行依賴收集。有Dep.target的對(duì)象會(huì)講Watcher的實(shí)例push到subs中,在對(duì)象被修改出發(fā)setter操作的時(shí)候dep會(huì)調(diào)用subs中的Watcher實(shí)例的update方法進(jìn)行渲染。
關(guān)于作者:染陌
Email:[email protected] or [email protected]
Github: https://github.com/answershuto
Blog:http://answershuto.github.io/
知乎專欄:https://zhuanlan.zhihu.com/ranmo
掘金: https://juejin.im/user/58f87ae844d9040069ca7507
osChina:https://my.oschina.net/u/3161824/blog
轉(zhuǎn)載請(qǐng)注明出處,謝謝。
歡迎關(guān)注我的公眾號(hào)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/84987.html
相關(guān)文章
深入淺出Vue響應(yīng)式原理
摘要:總結(jié)最后我們依照下圖參考深入淺出,再來(lái)回顧下整個(gè)過(guò)程在后,會(huì)調(diào)用函數(shù)進(jìn)行初始化,也就是過(guò)程,在這個(gè)過(guò)程通過(guò)轉(zhuǎn)換成了的形式,來(lái)對(duì)數(shù)據(jù)追蹤變化,當(dāng)被設(shè)置的對(duì)象被讀取的時(shí)候會(huì)執(zhí)行函數(shù),而在當(dāng)被賦值的時(shí)候會(huì)執(zhí)行函數(shù)。 前言 Vue 最獨(dú)特的特性之一,是其非侵入性的響應(yīng)式系統(tǒng)。數(shù)據(jù)模型僅僅是普通的 JavaScript 對(duì)象。而當(dāng)你修改它們時(shí),視圖會(huì)進(jìn)行更新。這使得狀態(tài)管理非常簡(jiǎn)單直接,不過(guò)理解...
vue.js源碼 - 剖析observer,dep,watch三者關(guān)系 如何具體的實(shí)現(xiàn)數(shù)據(jù)雙向綁定
摘要:雙向數(shù)據(jù)綁定的核心和基礎(chǔ)是其內(nèi)部真正參與數(shù)據(jù)雙向綁定流程的主要有和基于和發(fā)布者訂閱者模式,最終實(shí)現(xiàn)數(shù)據(jù)的雙向綁定。在這里把雙向數(shù)據(jù)綁定分為兩個(gè)流程收集依賴流程依賴收集會(huì)經(jīng)過(guò)以上流程,最終數(shù)組中存放列表,數(shù)組中存放列表。 Vue雙向數(shù)據(jù)綁定的核心和基礎(chǔ)api是Object.defineProperty,其內(nèi)部真正參與數(shù)據(jù)雙向綁定流程的主要有Obderver、Dep和Watcher,基于d...
從Vue.js源碼角度再看數(shù)據(jù)綁定
摘要:在學(xué)習(xí)過(guò)程中,為加上了中文的注釋,希望可以對(duì)其他想學(xué)習(xí)源碼的小伙伴有所幫助。數(shù)據(jù)綁定原理前面已經(jīng)講過(guò)數(shù)據(jù)綁定的原理了,現(xiàn)在從源碼來(lái)看一下數(shù)據(jù)綁定在中是如何實(shí)現(xiàn)的。 寫(xiě)在前面 因?yàn)閷?duì)Vue.js很感興趣,而且平時(shí)工作的技術(shù)棧也是Vue.js,這幾個(gè)月花了些時(shí)間研究學(xué)習(xí)了一下Vue.js源碼,并做了總結(jié)與輸出。文章的原地址:https://github.com/answershuto/le...
Vue源碼解析(2)-vue雙向數(shù)據(jù)綁定原理
摘要:與狀態(tài)同步非常困難通過(guò)添加觀察者監(jiān)測(cè)變化,如和。應(yīng)用中狀態(tài)的屬性會(huì)被監(jiān)測(cè),當(dāng)它們發(fā)生變化時(shí),只有依賴了發(fā)生變化屬性的元素會(huì)被重新渲染。 現(xiàn)代 js 框架存在的根本原因 然而通常人們(自以為)使用框架是因?yàn)椋核鼈冎С纸M件化;它們有強(qiáng)大的社區(qū)支持;它們有很多(基于框架的)第三方庫(kù)來(lái)解決問(wèn)題;它們有很多(很好的)第三方組件;它們有瀏覽器擴(kuò)展工具來(lái)幫助調(diào)試;它們適合做單頁(yè)應(yīng)用。 Keeping...
Vue2 源碼分析
摘要:應(yīng)用啟動(dòng)一般是通過(guò),所以,先從該構(gòu)造函數(shù)著手。構(gòu)造函數(shù)文件該文件只是構(gòu)造函數(shù),原型對(duì)象的聲明分散在當(dāng)前目錄的多個(gè)文件中構(gòu)造函數(shù)接收參數(shù),然后調(diào)用。 源碼版本:v2.1.10 分析目標(biāo) 通過(guò)閱讀源碼,對(duì) Vue2 的基礎(chǔ)運(yùn)行機(jī)制有所了解,主要是: Vue2 中數(shù)據(jù)綁定的實(shí)現(xiàn)方式 Vue2 中對(duì) Virtual DOM 機(jī)制的使用方式 源碼初見(jiàn) 項(xiàng)目構(gòu)建配置文件為 build/conf...
發(fā)表評(píng)論
0條評(píng)論
閱讀 2245·2021-09-22 15:25
閱讀 3623·2019-08-30 12:48
閱讀 2212·2019-08-30 11:25
閱讀 2345·2019-08-30 11:05
閱讀 730·2019-08-29 17:28
閱讀 3295·2019-08-26 12:16
閱讀 2616·2019-08-26 11:31
閱讀 1725·2019-08-23 17:08