你們好,我是卡頌。html
我是個戀舊的人,Github
頭像仍是上古時期端遊仙劍奇俠傳的截圖。前端
對於前端,若是能jQuery
一把梭,我是很開心的。vue
React
、Vue
的普及讓你們習慣了虛擬DOM
的存在。可是虛擬DOM
必定是最優解麼?react
舉個例子,要進行以下DOM
移動操做:markdown
// 變化前
abcd
// 變化後
dabc
複製代碼
用jQuery
時調用insertBefore
把d
挪到a
前面就行。而React
基於虛擬DOM
的Diff
會依次對abc
執行appendChild
,將他們依次挪到最後。app
1次DOM
操做 vs 3次DOM
操做,顯然前者更高效。框架
那麼有沒有框架能砍掉虛擬DOM
,直接對DOM
節點執行操做,實現全自動jQuery
?學習
有的,這就是最近出的petite-vue
。spa
閱讀完本文,你會從原理層面瞭解該框架,若是你還有精力,能夠在此基礎上深刻框架源碼。3d
能夠將原理歸納爲一句話:
創建
狀態
與更新DOM的方法
之間的聯繫
好比,對於以下DOM
:
<p v-show="showName">我是卡頌</p>
複製代碼
指望showName
狀態的變化能影響p
的顯隱(經過改變diaplay
)。
實際是創建showName的變化與調用以下方法的聯繫:
() => {
el.style.display = get() ? initialDisplay : 'none'
}
複製代碼
其中el
表明p
,get()
獲取showName
當前值。
再好比,對於以下DOM
:
<p v-text="name"></p>
複製代碼
name
改變後p
的textContent
會變爲對應值。
實際是創建name的變化與調用以下方法的聯繫:
() => {
el.textContent = toDisplayString(get())
}
複製代碼
因此,整個框架的工做原理呼之欲出:初始化時遍歷全部DOM
,根據各類v-xx
屬性創建DOM
與操做DOM的方法之間的聯繫。
當改變狀態後,會自動調用與其有關的操做DOM的方法,簡直就是全自動jQuery
。
因此,框架的核心在於:如何創建聯繫?
這部分源碼都收斂在@vue/reactivity
庫中。我並不想帶你精讀源碼,由於這樣很沒意思,看了還容易忘。
接下來我會經過一個故事爲你展現其工做原理,當你瞭解原理後若是感興趣能夠本身去看源碼。
咱們的目標是描述:狀態變化與更新DOM的方法之間的聯繫。說得再寬泛點,是創建狀態
與反作用
之間的聯繫。
即:狀態變化 -> 執行反作用
對於一段關係,能夠從當事雙方的角度描述,好比:
男生指着女生說:這是我女友。
接着女生指着男生說:這是我男友。
你做爲旁觀者,經過雙方的描述就知道他們處於一段戀愛關係。
推廣到狀態
與反作用
,則是:
反作用
指着狀態
說:我依賴這個狀態
,他變了我就會執行。
狀態
指着反作用
說:我訂閱了這個反作用
,當我變了後我會通知他。
能夠看到,發佈訂閱實際上是對一段關係站在雙方視角的闡述
舉個例子,以下DOM
結構:
<div v-scope="{num: 0}">
<button @click="num++">add 1</button>
<p v-show="num%2">
<span v-text="num"></span>
</p>
</div>
複製代碼
通過petite-vue
遍歷後的關係圖:
框架的交互流程爲:
觸發點擊事件,狀態num
變化
通知其訂閱的反作用
(effect1
與effect2
),執行對應DOM
操做
若是從情侶關係角度解讀,就是:
num
指着effect1
說:這是我女友。
effect1
指着num
說:這是我男友。
num
指着effect2
說:這是我女友。
effect2
指着num
說:這是我男友。
今天咱們學習了一個框架petite-vue
,他的底層實現由多段混亂的男女關係組成,上層是一個個直接操做DOM
的方法。
不知道看完後你有沒有興趣深刻了解下這種關係呢?
感興趣的話能夠看看Vue Mastery
的Vue 3 Reactivity
課程。