vue源碼解讀--組件更新(父組件的更新流程)

本節(jié)我們的示例如下

\bullet app.vue

\bullet child.vue

當(dāng)點(diǎn)擊按鈕缀旁,切換flag的值峭竣,此時(shí)將觸發(fā)get收集依賴并觸發(fā)set向dep分別notify粒督,這將在下一個(gè)tick中觸發(fā)更新彼棍,執(zhí)行patch娃惯,接收新舊兩個(gè)vnode

上一節(jié)跷乐,我們分析過,組件更新的分界點(diǎn)為sameVnode

? ??\star 當(dāng)前組件未定義key趾浅、tag為main愕提、非注釋節(jié)點(diǎn)、都有data定義潮孽。故return true揪荣。調(diào)用patchVnode,入?yún)椋号f的vnode往史、新的vnode仗颈、[]

? ??\star 用紅色框框圈出的位置,是針對組件而言椎例。vue在render過程中遇到子組件會調(diào)用createComponent方法挨决,該方法向組件data上掛載了hook(init、prepatch订歪、insert脖祈、destory);postpatch和update則是mergeVNodeHook時(shí)掛載的刷晋。在本次patch流程中的根vnode是app.vue的盖高,故先跳過(step:1)不看

? ? \star 每次render都會生成一個(gè)vnode慎陵,其children則保留著根節(jié)點(diǎn)的html元素對應(yīng)的vnode。故oldCh和ch拿到的都是組件vnode喻奥、空文本節(jié)點(diǎn)vnode席纽、button按鈕對應(yīng)的vnode。調(diào)用isPatchable

? ??????????\circ 根據(jù)之前分析得知撞蚕,vnode.componentInstance是在組件render過程中調(diào)用data.hook.init時(shí)緩存的润梯,換言之,只有組件的vnode有componentInstance值甥厦,那么同樣的纺铭,當(dāng)前的patch流程不是組件child,故不會進(jìn)入while循環(huán)刀疙,返回true

? ??????\star 返回patchVnode舶赔,調(diào)用cbs.update。該方法是在createPatchFunction過程中保存的hooks鍵('create',?'activate',?'update',?'remove',?'destroy')庙洼,對應(yīng)的值為createPatchFunction傳入的modules顿痪,即各個(gè)模塊對應(yīng)的創(chuàng)建或更新的鉤子函數(shù),如updateAttrs

? ??????????????\circ 進(jìn)入updateAttrs函數(shù)油够,對在標(biāo)簽上定義的屬性值進(jìn)行比對更新

? ??????????????\ominus 對attrs(id="app")進(jìn)行更新,我們這里兩次的id值是相同的蚁袭,假設(shè)id的值發(fā)生了變化,則調(diào)用setAttr

(從獲取的真實(shí)dom元素el調(diào)用的api可以看出石咬,vue是在一定的條件下新增或刪除一些屬性)

\star 因此得出結(jié)論揩悄,cbs.update實(shí)際上就是針對dom的各個(gè)模塊調(diào)用原生的一些dom方法進(jìn)行比對更新\star ? ? ? ? ? ? ??

????????\star 返回patchVnode,調(diào)用hook上的update針對組件做一些更新鬼悠,同樣的删性,由于當(dāng)前patch流程非組件vnode,故跳過

?????????\star 代碼向下焕窝,判斷vnode.text是否存在蹬挺。如果該值存在,則說明該組件只有一個(gè)文本節(jié)點(diǎn)它掂,因此只需要調(diào)用原生dom api設(shè)置根元素的textContent進(jìn)行簡單的文本更新即可

? ? ? ? ? \star 我們當(dāng)前并不滿足文本節(jié)點(diǎn)條件巴帮,故進(jìn)入if判斷,由于oldCh 和 ch來源自不同的引用虐秋,故條件為true榕茧,調(diào)用updateChildren方法,入?yún)椋篿d為app的div客给、新舊vnode用押、[]、undefine靶剑。也就是說蜻拨,在此之前池充,vue針對的是template內(nèi)的根元素做的更新,其子元素還未有任何操作? ?

? ??????????\star oldStartIdx=0缎讼、oldEndIdx=2纵菌、newStartIdx=0、newEndIdx=0休涤、oldStartVnode=組件vnode、oldEndVnode=button按鈕笛辟、newStartVnode=組件vnode功氨、newEndVnode=button按鈕

? ??????????\star 調(diào)用checkDuplicateKeys,判斷key是否重復(fù)手幢,因?yàn)榈湫偷膗l+li結(jié)構(gòu)下vue是要求我們給定不同的key的捷凄,因?yàn)関ue在更新階段會根據(jù)key進(jìn)行更新走不同的邏輯,因?yàn)檫@里是在確保key是唯一的

????????????\star ? 執(zhí)行while循環(huán)围来,這實(shí)際上就是我們常提起的高大上的diff算法的核心

? ??????????????????\circ 符合判斷跺涤,進(jìn)入while循環(huán)。走到sameVnode判斷中监透,再次調(diào)用patchVnode桶错,入?yún)椋盒屡f組件vnode、【】胀蛮、包含三個(gè)子元素的組件vnode院刁、0,重復(fù)之前的邏輯,在本次的patch流程中將進(jìn)入之前跳過的step

? ??????????????????????\odot step1

? ? ? ? ? ? ? ? ? ? ? ? ? ? --調(diào)用prepatch粪狼,入?yún)樾屡f組件vnode

? ? ? ? ? ? ? ? ? ? ? ? ? ? --調(diào)用updateChildComponent退腥,入?yún)樯弦淮?點(diǎn)擊按鈕前組件render過程中生成的vnode,是實(shí)際的渲染vnode)再榄、props(flag:true)狡刘、定義的事件、組件vnode困鸥、undefined嗅蔬。在該函數(shù)中將對一些值進(jìn)行訪問和更新,以觸發(fā)其set觸發(fā)notify更新窝革,因此將執(zhí)行子組件的patch過程

? ??????????\star 回到while循環(huán)购城,這次拿到的是中間的文本節(jié)點(diǎn),再次進(jìn)入patchvnode虐译,此次將執(zhí)行到nodeOps.setTextContent(elm,?vnode.text)更新text文本節(jié)點(diǎn)

? ??????????\star 再次回到while循環(huán)瘪板,本次拿到的是button按鈕,由于button沒有改變漆诽,因此實(shí)際上是沒有被更新的

? ? 當(dāng)三次更新完畢后侮攀,則app.vue更新流程結(jié)束

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末锣枝,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子兰英,更是在濱河造成了極大的恐慌撇叁,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件畦贸,死亡現(xiàn)場離奇詭異陨闹,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)薄坏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進(jìn)店門趋厉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人胶坠,你說我怎么就攤上這事君账。” “怎么了沈善?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵乡数,是天一觀的道長。 經(jīng)常有香客問我闻牡,道長净赴,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任澈侠,我火速辦了婚禮劫侧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘哨啃。我一直安慰自己烧栋,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布拳球。 她就那樣靜靜地躺著审姓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪祝峻。 梳的紋絲不亂的頭發(fā)上魔吐,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天,我揣著相機(jī)與錄音莱找,去河邊找鬼酬姆。 笑死,一個(gè)胖子當(dāng)著我的面吹牛奥溺,可吹牛的內(nèi)容都是我干的辞色。 我是一名探鬼主播,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼浮定,長吁一口氣:“原來是場噩夢啊……” “哼相满!你這毒婦竟也來了层亿?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤立美,失蹤者是張志新(化名)和其女友劉穎匿又,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體建蹄,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡碌更,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了洞慎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片针贬。...
    茶點(diǎn)故事閱讀 40,013評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖拢蛋,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蔫巩,我是刑警寧澤谆棱,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站圆仔,受9級特大地震影響垃瞧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜坪郭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一个从、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧歪沃,春花似錦嗦锐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至液走,卻和暖如春碳默,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背缘眶。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工嘱根, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人巷懈。 一個(gè)月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓该抒,卻偏偏與公主長得像,于是被迫代替她去往敵國和親砸喻。 傳聞我的和親對象是個(gè)殘疾皇子柔逼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內(nèi)容