智子: Vue Vapor年底釋出alpha版本,如果有資金支援

前端欧阳發表於2024-10-29

前言

在最近的Vue Fes大會上,Vue Vapor的作者智子大佬宣佈,如果能夠得到資金支援,那麼Vue Vapor年底就能釋出alpha版本了。

關注公眾號:【前端歐陽】,給自己一個進階vue的機會

智子也需要賺錢養活自己

根據尤大透露,過去一年以來智子接受贊助全職在為Vue Vapor工作。現在智子雖然還有贊助,但不再是全職的了。
t3

也就是說現在智子大佬也需要想辦法賺錢養活自己了,所以上週智子發了一個尋找贊助商的帖子。
t1

智子的目標也很簡單,能夠養活他就行了。並且表示為贊助商服務,開始雖然是封閉開發,最終還是會開源的。
t2

如果不尋求贊助,為了能夠養活自己智子就只能去找一份工作了。如果這樣Vapor的開發進度可能就會延緩,所以目前來說贊助計劃是目前最好的方式了。
t5

目前智子收到的贊助總額不到1000美元(包括尤大的)。

強如智子大佬,做開源也很難養活自己。歐陽也只能略盡綿薄之力(因為我最近也被通知12月底走人了,我們團隊將會只剩下leader了)
sponsor

現在的Vue Vapor

現在的Vue Vapor主要有三個特點:沒有虛擬DOM、高效能、更小的包體積。

沒有虛擬DOM:意思很簡單,就是在Vue Vapor中已經將虛擬DOM給幹掉了。

高效能:因為幹掉了虛擬DOM,瓶頸得以突破,所以效能相對提高了很多。
performance

更小的包體積:包體積大小減少了53.3%。

並且Vue Vapor是目前大家所使用的Vue版本的子集
subset

相比目前的Vue功能要少點,支援Composition API以及<script setup>

因為Vapor是目前Vue版本的子集,所以無虛擬DOM的Vapor模式和有虛擬DOM的vDom模式之間是互相相容的。
fusion

在Vapor元件中支援使用vDom模式的元件。同樣在vDom元件中也支援使用Vapor模式的元件。並且還支援只使用Vapor模式的情況。

並且Vue生態中的VueUseVue RouterPiniaNuxt元件庫等都會支援Vapor。
compatibility

同樣也支援jsx,不過需要引入unplugin-vue-jsx-vapor

Vapor的機制

先看一個普通的操作DOM的例子:

// Initialize
const container = document.createElement('div')
const label = document.createElement('h1')
const button = document.createElement('button')
button.textContent = 'Increase'

button.addEventListener('click', increase)
let count = 0
const render = () => {
  label.textContent = `Count: ${count}`
}
function increase() {
  count++
  render() // Re-render
}
render() // Initial render

document.body.append(container)
container.append(label, button)

在這個例子中主要有兩個元素:h1標籤和button按鈕。

h1標籤中渲染了count變數的值。

點選button按鈕觸發click事件執行increase函式,在函式中首先會執行count++,然後再去執行render函式。

render函式中將h1標籤中的值更新為最新值。

上面這個方案有個弊端,每次在click事件的回撥中除了常規的執行count++之外,還去手動呼叫了render函式。

設想一下,如果我們的業務程式碼裡面也這樣寫,那程式碼中將會到處都在呼叫render函式了,這樣的程式碼光想想都頭疼。

還好Vue的設計中有個優秀的響應式機制,並且還將響應式的功能抽取成一個單獨的包:@vue/reactivity

而Vue Vapor就是基於@vue/reactivity進行開發的,藉此實現當響應式資料改變後會自動更新DOM,無需去手動執行render函式。

使用@vue/reactivity改造後的程式碼如下:

import { effect, ref } from '@vue/reactivity'

// Initialize
const container = document.createElement('div')
const label = document.createElement('h1')
const button = document.createElement('button')
button.textContent = 'Increase'

button.addEventListener('click', increase)
const count = ref(0)
effect(() => {
  label.textContent = `Count: ${count.value}`
})
function increase() {
  count.value++
}

document.body.append(container)
container.append(label, button)

改造後的程式碼和原來的程式碼主要有三個不同:

  • 之前是直接使用let count = 0定義的變數,而改造後使用const count = ref(0)定義的響應式變數。

  • 之前的increase函式中除了執行count++之外,還需要去手動呼叫render()函式。而在新的程式碼中只會執行count.value++

  • 移除了render函式,替代他的是effect函式。在effect的回撥函式中同樣是進行DOM操作更新h1標籤中的值。

    effect函式和watchEffect很相似,當回撥中的響應式變數改變後就會重新執行回撥函式。這裡就是當響應式變數count改變後會重新執行回撥函式,在回撥函式中進行DOM操作更新h1標籤中的值。

這也就是Vapor基於@vue/reactivity實現的響應式原理,在這個過程中完全沒有虛擬DOM的介入。當響應式變數改變後會執行對應的effect回撥函式,在回撥函式中直接去更新DOM即可。

看到這裡有的小夥伴會有疑問,這個effect函式以及裡面操作DOM的程式碼需要我們自己手寫嗎?

當然不需要手動去寫!!在編譯時Vapor會自動生成一個effect回撥函式,以及回撥函式里面更新DOM的程式碼。

這個是上面的例子在Vue Vapor SFC Playground上面經過編譯後的js程式碼,如下圖:
playground

從上圖中可以看到Vapor模式下經過編譯後會自動生成一個effect回撥函式,並且在回撥函式中會去直接操作DOM。

至於編譯時是如何生成effect回撥函式,需要等Vapor穩定後歐陽會繼續寫文章講解。

總結

無虛擬DOM的Vapor模式是有虛擬DOM的vDom模式的子集,並且他們之間支援component元件混用。拋棄了虛擬DOM,Vapor輕裝上陣後,效能以及包體積相比傳統的vDom模式有了很大的提升。最後就是智子現在在尋求贊助商,讓他能夠全職開發Vue Vapor的同時能夠養活自己。

關注公眾號:【前端歐陽】,給自己一個進階vue的機會

另外歐陽寫了一本開源電子書vue3編譯原理揭秘,看完這本書可以讓你對vue編譯的認知有質的提升。這本書初、中級前端能看懂,完全免費,只求一個star。

相關文章