摘要:哎喲,這個(gè)鉤子是,更新一個(gè)節(jié)點(diǎn),就馬上執(zhí)行該節(jié)點(diǎn)鉤子的喔。剛剛創(chuàng)建的指令,指令肯定都是新的,就沒必要往下走,浪費(fèi)性能某個(gè)舊指令不存在新指令對(duì)象中。證明這個(gè)指令已經(jīng)被移除不是新節(jié)點(diǎn)參數(shù)
寫文章不容易,點(diǎn)個(gè)贊唄兄弟
專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧
研究基于 Vue版本 【2.5.17】
如果你覺得排版難看,請(qǐng)點(diǎn)擊 下面鏈接 或者 拉到 下面關(guān)注公眾號(hào)也可以吧
【Vue原理】Directive - 白話版
今天是除夕啦,大家新年快樂!身體健康!2019多多開花,耶,嗨起來!
言歸正傳!
我相信應(yīng)該大家應(yīng)該都使用過 Directive 指令,有時(shí)為了能夠直接操作DOM,而指令中最重要的莫過于是 鉤子函數(shù)了,指令一共有五個(gè)鉤子函數(shù),他們不會(huì)在不同的階段觸發(fā),文檔也已經(jīng)說明
當(dāng)然了,其實(shí)你只要了解它是什么時(shí)候觸發(fā)的,就完全可以用在項(xiàng)目。但是我們是不會(huì)滿足于此的,我要知道他是怎么觸發(fā)的,怎么調(diào)用到我設(shè)置的鉤子的
今天,我們就來簡(jiǎn)單說一下這幾個(gè)鉤子都是怎么被調(diào)用的
你能相信我寫 Directive 花了一個(gè)星期啊,不是有多難,而是我不知道怎么下手寫啊,根本不知道怎么描述會(huì)簡(jiǎn)單好了解,吐血
鉤子如何調(diào)用首先,Vue 在綁定了指令的DOM 創(chuàng)建之后,插入頁面之前,對(duì)一些DOM 本身的事件或者屬性等進(jìn)行處理。
其中,就包含對(duì)本DOM的所有指令進(jìn)行處理
怎么處理呢?每一個(gè)鉤子函數(shù)都不一樣,所以我們會(huì)分不同鉤子說明
首先,處理時(shí),Vue 要判斷哪些指令是新的還是舊的
所以需要比較 舊節(jié)點(diǎn)上的指令 和 新節(jié)點(diǎn)上的指令
比如 新指令比舊指令 多了一個(gè)指令 ,如下
// 新指令 newDir 如下 newDir={ "v-test":{ name: "test", rawName: "v-test" }, "v-test2":{ name:"test2" rawName:"v-test2" } } // 舊指令 oldDir 如下,少了一個(gè) v-test2 oldDir={ "v-test":{ name: "test", rawName: "v-test" } }
如果是新指令
遍歷新指令對(duì)象時(shí),當(dāng) "v-test2" 指令不存在 舊指令對(duì)象中,則表示這個(gè)是新指令,需要初始化
1、bind
遍歷遇到新指令時(shí),直接執(zhí)行 bind 鉤子函數(shù),并傳入?yún)?shù)
for(i in newDir){ var dir = newDir[i] if( !oldDir[i]){ dir.bind(....參數(shù)) } }
2、inserted
按文檔的說明,我們就知道,inserted 是在節(jié)點(diǎn)插入父節(jié)點(diǎn)調(diào)用
而所有節(jié)點(diǎn)的所有鉤子,會(huì)放在同一時(shí)間一起處理,并不是插入一個(gè)節(jié)點(diǎn),就執(zhí)行一個(gè)節(jié)點(diǎn)的 inserted 鉤子
inserted 分為 保存 和 執(zhí)行 兩個(gè)步驟
因?yàn)閕nserted 需要在 節(jié)點(diǎn)插入之后才執(zhí)行,而現(xiàn)在處理是在 節(jié)點(diǎn)插入之前,所以只能先保存起來,用于后面執(zhí)行。
簡(jiǎn)單實(shí)現(xiàn)如下
// 1、使用一個(gè)數(shù)組 保存 本 DOM 的 所有新指令的 inserted 鉤子 var dirInserted = [] for(i in newDir){ var dir = newDir[i] if( !oldDir[i]){ dir.bind(....參數(shù)) dirInserted.push(dir.inserted) } } // 2、新建一個(gè)函數(shù),專門遍歷這個(gè)數(shù)組,逐個(gè)執(zhí)行 inserted 鉤子 var callback = function(){ for(var i=0;i=dirInserted.length;i++){ dirInserted[i](....參數(shù)) } } // 3、 把 callback 保存進(jìn)當(dāng)前節(jié)點(diǎn)的一個(gè)地方,為了后面使用 dom.insert = callback // 4、把 所有含有 callback 的節(jié)點(diǎn),也放到一個(gè)數(shù)組 var insertedVnodeQueue=[] if( 存在inserted 的 dom ){ insertedVnodeQueue.push( dom ) } // 5、當(dāng)節(jié)點(diǎn)插入后,開始遍歷insertedVnodeQueue for (var i = 0; i為了驗(yàn)證 inserted 鉤子 并不是插入一個(gè)節(jié)點(diǎn),就執(zhí)行一次,我特地在 插入節(jié)點(diǎn)的函數(shù)后面打印一句話,于是可以看到如下的打印順序
bind---> SPAN 插入DOM span bind---> P 插入DOM p bind---> DIV 插入DOM div inserted---> SPAN inserted---> P inserted---> DIV如果是舊指令
遍歷新指令對(duì)象時(shí),當(dāng) v-test 指令也存在舊指令對(duì)象中,則表示這個(gè)是舊指令,需要更新
1、update
碰到舊指令,會(huì)直接執(zhí)行 update 鉤子函數(shù),并傳入?yún)?shù)
for(i in newDir){ var dir = newDir[i] if( !oldDir[i]){ dir.bind(....參數(shù)) }else{ dir.update(...參數(shù)) } }2、componentUpdated
componentUpdated 的保存方式 和 inserted 差不多,但是執(zhí)行方式卻不一樣。
哎喲,這個(gè)鉤子是,更新一個(gè)節(jié)點(diǎn),就馬上執(zhí)行該節(jié)點(diǎn)鉤子的喔。跟 inserted 完全不一樣喔,雖然我也不懂為什么
我也在源碼內(nèi)更新 DOM 后加了一句打印,然后我們看下執(zhí)行順序
update---> DIV update---> SPAN 完成更新DOM span componentUpdated---> SPAN update---> P 完成更新DOM p componentUpdated---> P 完成更新DOM div componentUpdated---> DIV3、unbind
當(dāng) 新指令 比 舊指令少了,比如下面這樣
// 舊指令 { "v-test":{ name: "test", rawName: "v-test" }, "v-test2":{ name:"test2" rawName:"v-test2" } } // 新指令 { "v-test":{ name: "test", rawName: "v-test" } }那么 v-test2 指令被去掉了,這時(shí)肯定會(huì)觸發(fā) unbind 鉤子
unbind 鉤子也是直接調(diào)用的,沒有那么多轉(zhuǎn)來轉(zhuǎn)去的邏輯幺蛾子,但是需要兩個(gè)判斷條件
1、不是新節(jié)點(diǎn)。剛剛創(chuàng)建的指令,指令肯定都是新的,就沒必要往下走,浪費(fèi)性能
2、某個(gè)舊指令 不存在 新指令對(duì)象中。證明這個(gè)指令已經(jīng)被移除
if( 不是新節(jié)點(diǎn) ){ for(i in oldDir){ var dir = oldDir[i] if( !newDir[i]){ dir.unbind(....參數(shù)) } } }
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/105200.html
寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5.17】 如果你覺得排版難看,請(qǐng)點(diǎn)擊 下面鏈接 或者 拉到 下面關(guān)注公眾號(hào)也可以吧 【Vue原理】Mixins - 源碼版 今天探索的是 mixins 的源碼,mixins 根據(jù)不同的選項(xiàng)類型會(huì)做不同的處理 篇幅會(huì)有些長,...
摘要:而我覺得現(xiàn)在出一個(gè)白話版,是讓大家有興趣去研究源碼的時(shí)候,可以提前理清一下思路。相當(dāng)于封裝,提取公共部分。顯然,今天我不是來教大家怎么用的,怎么用看文檔就好了,我是講解生命的真諦內(nèi)部的工作原理。而這個(gè)不會(huì)合并,直接替換掉整個(gè)選項(xiàng) 寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版...
摘要:首先,兄弟,容我先說幾句涉及源碼很多,篇幅很長,我都已經(jīng)分了上下三篇了,依然這么長,但是其實(shí)內(nèi)容都差不多一樣,但是我還是毫無保留地給你了。 寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5.17】 如果你覺得排版難看,請(qǐng)點(diǎn)擊 下面鏈接 或者 拉到 下面關(guān)注公眾號(hào)也...
摘要:所以我今后打算把每一個(gè)內(nèi)容分成白話版和源碼版。有什么錯(cuò)誤的地方,感謝大家能夠指出響應(yīng)式系統(tǒng)我們都知道,只要在實(shí)例中聲明過的數(shù)據(jù),那么這個(gè)數(shù)據(jù)就是響應(yīng)式的。什么是響應(yīng)式,也即是說,數(shù)據(jù)發(fā)生改變的時(shí)候,視圖會(huì)重新渲染,匹配更新為最新的值。 寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 V...
摘要:如果沒有緩存,我們將不可避免的多次執(zhí)行的現(xiàn)在我們要開始講解,是如何判斷是否使用緩存的首先計(jì)算后,會(huì)把計(jì)算得到的值保存到一個(gè)變量中。當(dāng)使用緩存時(shí),就直接返回這個(gè)變量。 寫文章不容易,點(diǎn)個(gè)贊唄兄弟專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5.17】 如果你覺得排版難看,請(qǐng)點(diǎn)擊 下面鏈接 或...
閱讀 3923·2021-11-24 09:38
閱讀 3099·2021-11-17 09:33
閱讀 3874·2021-11-10 11:48
閱讀 1243·2021-10-14 09:48
閱讀 3133·2019-08-30 13:14
閱讀 2554·2019-08-29 18:37
閱讀 3396·2019-08-29 12:38
閱讀 1421·2019-08-29 12:30