如何在不看源碼狀況下學petite-vue源碼

前言

怎麼快怎麼來,你們的時間都寶貴,用最短的時間學到最多的知識。

咱們能夠將petite-vue理解爲:用真實DOM取代Vue模版的簡易Vuehtml

好比以下Demovue

<script type="module">
  import { createApp } from '../src'
  createApp({count: 0}).mount()
</script>

<div v-scope> <button @click="count++">add 1</button> <p>{{count}}</p> </div>  
複製代碼

div及其子孫節點是真實的DOM標籤,因此頁面初始化時以下:node

接着執行以下代碼,完成petite-vue初始化:react

createApp({count: 0}).mount()
複製代碼

此時頁面:git

讀框架源碼切忌一上手就從入口函數一路調試,很容易就懵逼了。正確的方式是像剝洋蔥同樣一層一層剝開:github

這好像是大蒜?

因此,讓咱們先從Performance面板看看首屏渲染的調用棧:框架

調用棧大致分爲藍框、紅框兩部分,先看左邊藍框部分:函數

經過createContextreactive關鍵詞判斷大概是建立響應式上下文。至於響應式的含義,咱們還不清楚。post

接着看右邊紅框部分:url

從調用棧深度、頁面渲染的效果咱們猜想,這部分作的工做包括:

  • 遍歷DOM

  • 完成數據與視圖的雙向綁定

  • 初始化渲染

接下來,咱們來驗證猜測。

注意,到目前爲止,咱們一行源碼都還沒看

驗證遍歷DOM

調用棧中walkwalkChildren被調用屢次,大機率他們就是具體遍歷工做執行的方法,讓咱們確認下。

在源碼walk方法中打上log

export const walk = (node: Node, ctx: Context): ChildNode | null | void => {
  console.log('walk', node);
  // ... 
}
複製代碼

排除換行符"\n "對應的文本節點,打印順序以下:

walk div
walk <button>add 1</button>
walk "add 1"
walk <p>0</p>
walk "0"
複製代碼

從打印結果看,這是個深度優先遍歷(若是有子節點就遍歷子節點,沒有子節點就遍歷兄弟節點)

顯然,petite-vue mount時採用深度優先遍歷,並對遍歷到的每一個與上下文狀態相關的DOM節點進行處理。

Demo中,上下文包含狀態{count: 0}

createApp({count: 0}).mount()
複製代碼

在遍歷後<p>{{count}}</p>變爲<p>0</p>

肯定雙向綁定的粒度

接下來咱們須要確認雙向綁定的做用範圍,即:

觸發更新後,多大範圍的DOM會被從新遍歷並執行相應DOM操做?

打開Performance後,點擊<button>add 1</button>觸發更新:

能夠看到,沒有任何walkwalkChildren(或相似遍歷過程),只調用了reactiveEffect一個方法就更新了DOM

這意味着mount時的深度優先遍歷創建了狀態更新DOM的方法之間一一對應的關係。

由於對應關係肯定了,就再也不須要額外的遍歷過程肯定須要變化的DOM

當更新狀態後,只須要找到與他有關係的更新DOM的方法執行就行。

好比:將count狀態與以下函數創建聯繫:

function setCount(value) {
  p.textContent = value;
}
複製代碼

每當count變化後調用setCount(count)就能更新p對應DOM

因此,petite-vue的工做原理,主要包括兩點:

  1. mount時深度優先遍歷DOM,對有狀態的DOM(好比<p>{{count}}</p>)創建狀態更新DOM的方法之間一一對應的關係

  2. update時找到該狀態對應的更新DOM的方法並執行

能夠看到,即便不深刻源碼,也能大致瞭解工做流程。

若是你想更進一步,好比了解關係是如何創建的(涉及到響應式更新),那麼就須要深刻源碼了。

這裏推薦Vue MasteryVue 3 Reactivity課程,能夠補齊響應式更新這塊知識。

總結

本文介紹了複雜框架源碼的閱讀辦法 —— 即從抽象到具體。

  1. mount時與update時的調用棧推導出總體工做流程

  2. 總體工做流程中發現核心知識 —— 響應式更新

當掌握總體工做流程響應式更新後,再閱讀本身感興趣的部分纔不至於陷入龐大的代碼量中。

你,學廢了麼?

最後,創做不易,若是對你們有所幫助,但願你們點贊支持,有什麼問題也能夠在評論區裏討論😄~

若是你以爲這篇文章對你有點用的話,麻煩請給咱們的開源項目點點star: http://github.crmeb.net/u/defu 不勝感激 !
來自 「開源世界 」 ,連接:   https://ym.baisou.ltd/post/776.html
相關文章
相關標籤/搜索