中國人中庸之道,中國人造的框架呢?

你們好,我是卡頌。前端

都說中國人講究中庸之道,中國人造的框架講究麼?數組

本文會從原理層面講解Vue是如何在運行時與編譯時之間保持中庸的平衡。前端框架

UI = fn(state)

幾乎全部前端框架工做原理都能用以下公式歸納:markdown

UI = fn(state)
複製代碼

UI(視圖)能夠經過state(狀態)通過fn(框架)計算得出。框架

然而具體原理上,框架之間卻千差萬別。spa

能夠按照更新粒度將他們分爲三類:3d

  • 樹級更新code

  • 組件級更新orm

  • 節點級更新xml

更新粒度沒有優劣之分,只是對應不一樣的實現

接下來咱們簡單瞭解下不一樣粒度更新方式的實現原理。

假設有以下組件樹,其中Cpn是一個自定義組件,內部結構爲ul>li*2

咱們但願將Cpn內的一個li更新爲黃色:

樹級更新

樹級更新的框架會再生成一棵完整虛擬DOM樹,生成過程當中與以前的虛擬DOM樹對應節點進行比較:

找到變化的節點後,執行對應DOM操做。

樹級更新框架的特色是:

  • 依賴虛擬DOM

  • 不關心觸發更新的節點(由於會經過虛擬DOM的全樹對比找到他)

採用這種更新方式最有名的框架就是React

組件級更新

上面的例子,若是是組件級更新框架。

會找到觸發更新節點所在組件,生成該組件的虛擬DOM樹(而不是全樹的虛擬DOM樹),生成過程當中與該組件以前的虛擬DOM樹對應節點進行比較:

找到變化的節點後,執行對應DOM操做。

組件級更新框架的特色是:

  • 依賴虛擬DOM

  • 關心觸發更新的節點(虛擬DOM的對比會做用於該節點所在組件)

採用這種更新方式最有名的框架就是Vue

節點級更新

若是是節點級更新框架,在編譯時會根據狀態變化對應的DOM變化直接生成對應方法,當狀態改變後直接調用對應方法。

上面的例子,在編譯時會關聯color狀態與changeColor方法:

function changeColor(newColor) {
  li.style.color = newColor;
}
複製代碼

當改變color狀態後直接調用changeColor方法更新li對應DOM

節點級更新框架的特色是:

  • 不依賴虛擬DOM,依賴預編譯(創建狀態與改變DOM的方法之間的聯繫)

  • 關心觸發更新的節點(節點狀態與更新方法一一對應)

採用這種更新方式最有名的框架就是Svelte

中庸的Vue3

Vue做爲組件級更新表明,更新粒度介於樹級節點級之間。那究竟是中間偏左呢,仍是中間偏右呢?

Vue3說:

我要反覆橫跳,兩邊我都要

Vue3中包含三種樹狀結構:

描述視圖的樹 -> 虛擬DOM樹 -> 真實DOM樹
複製代碼

其中描述視圖的樹官方推薦使用模版語法,但也能使用JSX

無論是哪一種方式,最終都會轉化爲虛擬DOM樹

當使用JSX時,Vue3擁有了React運行時的靈活性,此時的Vue3能夠看做是增強版React + Mobx

當使用模版語法Vue3引入了預編譯技術。此時能夠將Vue3的工做流程細化爲四步:

描述視圖的樹 -> VNode樹 -> Block數組 -> 真實DOM樹
複製代碼

其中VNode樹就是常規意義的虛擬DOM樹Block數組則爲VNode樹中對狀態有依賴,會變化的那部分VNode組成的數組。

好比,對於以下模版語法:

<template>
  <section> <div>i am</div> <p>{{name}}</p> </section>
</template>
複製代碼

sectiondiv不包含狀態,不會變化,因此會轉化爲VNode,可是沒有對應Block

p包含狀態name,會轉化爲VNodeBlock

當該template所在組件觸發name狀態變化,以前須要依次建立sectiondivpVNode並進行比較。

有了預編譯技術後只須要遍歷Block數組進行比較。

用上文的例子即只須要對比一個li節點:

在這種狀況下,雖然是使用虛擬DOM組件級更新框架,可是已經很接近節點級更新框架了。

總結

本文按更新粒度介紹了三種不一樣類型的框架,以及Vue3在選擇JSX模版語法時在靈活性與更新粒度間的靈活變化。

能夠說是很符合中庸之道了。

有人會問,使用Vue3的用戶大部分都能接受模版語法,爲何不直接拋棄虛擬DOM,使用預編譯技術,實現真正的節點級更新

一方面,虛擬DOM使框架脫離具體的視圖層,更方便跨端渲染。

另外一方面,Vue2社區生態積累了大量基於虛擬DOM的庫。

若是是你,在這種狀況下會做何選擇呢?

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息