最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue?Vapor的實現(xiàn)原理舉例詳解(原來這么簡單)

 更新時間:2026年06月12日 08:35:30   作者:Cobyte  
Vue Vapor是Vue?3.4+引入的實驗性功能,通過完全跳過虛擬DOM(Virtual?DOM)的生成與比對過程,直接操作真實DOM實現(xiàn)性能飛躍,這篇文章主要介紹了Vue Vapor實現(xiàn)原理的相關(guān)資料,需要的朋友可以參考下

前言

我們了解了 SolidJS 的基礎(chǔ)實現(xiàn)原理之后,再去探索實現(xiàn) Vue Vapor 就比較容易了,在 Vue3 中數(shù)據(jù)響應(yīng)式部分是獨立成了一個庫,我們可以直接使用 @vue/reactivity 這個庫響應(yīng)式,然后再去實現(xiàn)運行時部分。為了方便開發(fā),我們這里先搭建一個 Vite 的開發(fā)環(huán)境。

手動搭建一個 vite 開發(fā)環(huán)境

首先創(chuàng)建一個項目目錄 vue-vapor-cobyte-test,然后進到目錄里面進行 npm 項目的初始化:

npm init -y

然后安裝 vite@vue/reactivity

pnpm add vite @vue/reactivity 

然后修改 package.json 文件的 scripts 選項設(shè)置 vite 的啟動命令:

  "scripts": {
+    "dev": "vite"
  },

在開發(fā)期間 Vite 是一個服務(wù)器,所以我們需要創(chuàng)建 vite 的啟動入口文件 index.html,內(nèi)容如下:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vue Vapor</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="./src/main.js"></script>
  </body>
</html>

然后我們創(chuàng)建一個 src 目錄,在 src 根目錄創(chuàng)建一個 main.js 文件,內(nèi)容如下:

const root = document.getElementById('app')
root.textContent = '掘金簽約作者:Cobyte'

到此我們基礎(chǔ)的 Vite 開發(fā)環(huán)境就搭建完成了,我們通過命令來啟動它:

pnpm dev

頁面渲染結(jié)果如下:

我們可以看到已經(jīng)成功啟動了我們的項目,接下來我們就在這個 Vite 的開發(fā)環(huán)境中探索 Vue Vapor 的實現(xiàn)原理吧。

Vue Vapor 的核心原理實現(xiàn)

任何復(fù)雜的框架,只有通過最簡單的代碼去實現(xiàn)它的基本運行邏輯,才算是真正掌握了它實現(xiàn)原理。所謂高端的技術(shù)往往采用最原始的編程方式,還有那一句名言:Atwood 定律:Any application that can be written in JavaScript, will eventually be written in JavaScript. (翻譯過來即是:凡是能用 JavaScript 寫出來的,最終都會用 JavaScript 寫出來)。

我們通過前面對 SolidJS 的實現(xiàn)原理的探索,在此基礎(chǔ)之上,我們再去實現(xiàn) Vue Vapor 則比較容易了,就像我們了解了 Vue 的數(shù)據(jù)響應(yīng)式原理之后,再去了解 Mobx 的實現(xiàn)原理也變得簡單一樣,因為從宏觀角度來看它們背后的實現(xiàn)原理是相似的,甚至可以說是一樣的。

首先我們可以把 SolidJS 中的模板生成函數(shù)直接拿過來。

function template(html) {
    let node
    const create = () => {
        const t = document.createElement("template")
        t.innerHTML = html
        return t.content.firstChild
    }
    const fn = () => (node || (node = create())).cloneNode(true)
    return fn 
}

我們之前寫的 SolidJS 的組件如下:

接著我們像 SolidJS 那樣寫一個組件,同時響應(yīng)式變量我們則通過 @vue/reactivity 來生成:

// 生成創(chuàng)建 button 標簽的函數(shù)
const _tmpl$ = template('<button></button>')
const App = () => {
    const count = ref(0)
    // 真正進行創(chuàng)建模板內(nèi)容的地方
    const el = _tmpl$()
    el.addEventListener('click', () => {
        count.value ++
    })
    insert(el, count)
    return el
}

接著我們把 render 和 insert 方法也拿過來,我們之前寫的如下:

現(xiàn)在我們需要對 insert 方法進行改造一下,使用 @vue/reactivity 的 effect 函數(shù)實現(xiàn)依賴收集。

function render(component, parent) {
    parent.appendChild(component)
}

function insert(parent, accessor) {
    effect(() => {
        parent.textContent = accessor.value
    })
}

這樣我們就可以在實現(xiàn)無虛擬DOM的應(yīng)用了,并且可以自動更新。

const root = document.getElementById('app')
render(App(), root)

渲染結(jié)果如下:

完整代碼如下:

import { ref, effect } from '@vue/reactivity'
function template(html) {
    let node
    const create = () => {
        const t = document.createElement("template")
        t.innerHTML = html
        return t.content.firstChild
    }
    const fn = () => (node || (node = create())).cloneNode(true)
    return fn 
}

function render(component, parent) {
    parent.appendChild(component)
}

function insert(parent, accessor) {
    effect(() => {
        parent.textContent = accessor.value
    })
}

// 生成創(chuàng)建 button 標簽的函數(shù)
const _tmpl$ = template('<button></button>')
const App = () => {
    const count = ref(0)
    // 真正進行創(chuàng)建模板內(nèi)容的地方
    const el = _tmpl$()
    el.addEventListener('click', () => {
        count.value++
    })
    insert(el, count)
    return el
}
const root = document.getElementById('app')
render(App(), root)

Vue Vapor 設(shè)計原理

我們知道 Vue Vapor 是在 Vue3 的設(shè)計基礎(chǔ)上實現(xiàn)的一個無虛擬 DOM 的版本,那么也就是說它應(yīng)該是需要兼容目前 Vue3 的語法的,不然就又是一個新框架了。我們在上述實現(xiàn)的小 demo 是在 SolidJS 加 Vue3 的響應(yīng)式庫實現(xiàn)的,總體風(fēng)格是 SolidJS 的設(shè)計風(fēng)格,很明顯上述的實現(xiàn)是不兼容目前 Vue3 的語法的,所以我們還需要進行迭代我們的功能。

那么我們要兼容 Vue3 的語法,首先需要修改的就是我們的 render 函數(shù)的調(diào)用方式,我們目前所實現(xiàn)的 App 組件是一個函數(shù)組件,在我們原來 Vue3 中,render 函數(shù)第一個參數(shù)則是一個對象或者一個函數(shù),因為 Vue3 中的組件在數(shù)據(jù)類型上進行區(qū)分,就只有兩種,一種是虛擬DOM 對象(也就是我們平時所寫的 .vue 文件最后會被編譯成一個對象),一種則是函數(shù)(也就是組件函數(shù))。

調(diào)用方式修改如下:

- render(App(), root)
+ render(App, root)

接著我們修改 render 函數(shù):

function render(comp, container) {
    const render = typeof comp === 'function' ? comp : comp.render
    const block = render()
    insert(block, container)
}

如果是組件函數(shù)則組件函數(shù)本身就是 render 渲染函數(shù),否則就是組件對象上的 render 函數(shù)。得到 render 渲染函數(shù)后,執(zhí)行渲染函數(shù)得到真實 DOM,然后掛載到對應(yīng)的根節(jié)點上。

insert 函數(shù)的修改則如下:

function insert(block, parent, anchor = null) {
    parent.insertBefore(block, anchor)
}

在 SolidJS 中,依賴收集的副作用函數(shù)是放在 insert 函數(shù)中,我們也可以放在編譯后的組件函數(shù)中,所以我們的對編譯后的組件修改如下:

const App = () => {
    // 生成創(chuàng)建 button 標簽的函數(shù)
    const _tmpl$ = template('<button></button>')  
    const count = ref(0)
    // 真正進行創(chuàng)建模板內(nèi)容的地方
    const el = _tmpl$()
    el.addEventListener('click', () => {
        count.value ++
    })
    effect(() => {
        el.textContent = count.value
    })
    return el
}

渲染結(jié)果如下:

完整代碼如下:

import { ref, effect } from '@vue/reactivity'
function template(html) {
    let node
    const create = () => {
        const t = document.createElement("template")
        t.innerHTML = html
        return t.content.firstChild
    }
    const fn = () => (node || (node = create())).cloneNode(true)
    return fn 
}

function render(comp, container) {
    const render = typeof comp === 'function' ? comp : comp.render
    const block = render()
    insert(block, container)
}

function insert(block, parent, anchor) {
    parent.insertBefore(block, anchor)
}

const App = () => {
    const _tmpl$ = template('<button></button>')
    const count = ref(0)
    const el = _tmpl$()
    el.addEventListener('click', () => {
        count.value++
    })
    effect(() => {
        el.textContent = count.value
    })
    return el
}
const root = document.getElementById('app')
render(App, root)

我們可以看到 Vue Vapor 核心實現(xiàn)的代碼 50 行都不到。

總結(jié)

本文從零開始搭建了一個基于 Vite 的開發(fā)環(huán)境,并借助 @vue/reactivity 響應(yīng)式庫,成功實現(xiàn)了一個極簡版的 Vue Vapor 運行時核心。通過對比 SolidJS 的實現(xiàn)思路,我們看到了無虛擬 DOM 框架的基本模式:模板編譯生成 DOM 元素、利用響應(yīng)式系統(tǒng)的 effect 自動追蹤依賴并直接更新 DOM 內(nèi)容。整個核心代碼僅 50 行左右,卻完整展現(xiàn)了 Vue Vapor 的設(shè)計精髓——拋棄虛擬 DOM,回歸原生 DOM 操作,同時保持與 Vue3 組件語法的兼容性。

關(guān)鍵實現(xiàn)步驟包括:

  1. 使用 template 函數(shù)靜態(tài)克隆 DOM 節(jié)點,提升創(chuàng)建效率;
  2. 通過 ref 定義響應(yīng)式狀態(tài),利用 effect 建立數(shù)據(jù)與視圖的綁定;
  3. 組件函數(shù)直接返回真實 DOM 節(jié)點,由 render 函數(shù)完成掛載;
  4. 事件監(jiān)聽直接綁定在原生元素上,無需額外代理。

這一實現(xiàn)不僅驗證了 “任何能用 JavaScript 寫出的最終都會用 JavaScript 寫出” 的理念,也為深入理解 Vue Vapor 后續(xù)的指令系統(tǒng)、組件化、調(diào)度更新等進階特性奠定了扎實的基礎(chǔ)。無虛擬 DOM 的路徑在性能敏感場景下具有天然優(yōu)勢,Vue Vapor 正是 Vue 生態(tài)對這一方向的積極探索。

到此這篇關(guān)于Vue Vapor的實現(xiàn)原理的文章就介紹到這了,更多相關(guān)Vue Vapor實現(xiàn)原理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue實現(xiàn)加載頁面自動觸發(fā)函數(shù)(及異步獲取數(shù)據(jù))

    vue實現(xiàn)加載頁面自動觸發(fā)函數(shù)(及異步獲取數(shù)據(jù))

    這篇文章主要介紹了vue實現(xiàn)加載頁面自動觸發(fā)函數(shù)(及異步獲取數(shù)據(jù)),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • 使用WebStorm運行vue項目的詳細圖文教程

    使用WebStorm運行vue項目的詳細圖文教程

    在WebStorm中怎么打開一個已有的項目,這個不用多說,那么如何運行一個vue項目呢?下面這篇文章主要給大家介紹了關(guān)于使用WebStorm運行vue項目的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • Vue計算屬性與偵聽器和過濾器超詳細介紹

    Vue計算屬性與偵聽器和過濾器超詳細介紹

    這篇文章主要介紹了Vue計算屬性與偵聽器和過濾器,文中通過示例代碼介紹的非常詳細。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-10-10
  • 基于vue實現(xiàn)滾動條滾動到指定位置對應(yīng)位置數(shù)字進行tween特效

    基于vue實現(xiàn)滾動條滾動到指定位置對應(yīng)位置數(shù)字進行tween特效

    這篇文章主要介紹了基于vue實現(xiàn)滾動條滾動到指定位置對應(yīng)位置數(shù)字進行tween特效,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-04-04
  • Vue3中Reactive的使用詳解

    Vue3中Reactive的使用詳解

    Vue 3 的 Composition API 帶來了強大的 reactive 函數(shù),它允許你在 Vue 應(yīng)用程序中創(chuàng)建響應(yīng)式數(shù)據(jù),本文我們將深入探討 Vue 3 的 reactive,并提供一些注意事項和解決方案,希望可以幫助打更好地使用它
    2023-11-11
  • ant-design-vue按需加載的坑的解決

    ant-design-vue按需加載的坑的解決

    這篇文章主要介紹了ant-design-vue按需加載的坑的解決,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • Element?Plus修改表格行和單元格樣式詳解

    Element?Plus修改表格行和單元格樣式詳解

    在使用Element Plus中的table組件展示數(shù)據(jù)時,由于需要對表格行內(nèi)數(shù)據(jù)的數(shù)據(jù)進行修改,下面這篇文章主要給大家介紹了關(guān)于Element?Plus修改表格行和單元格樣式的相關(guān)資料,需要的朋友可以參考下
    2022-04-04
  • vue文件上傳Required request part ‘file‘ is not present問題

    vue文件上傳Required request part ‘file‘ is&n

    這篇文章主要介紹了vue文件上傳Required request part ‘file‘ is not present問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • 在Vue3中使用CSS Modules實現(xiàn)樣式隔離

    在Vue3中使用CSS Modules實現(xiàn)樣式隔離

    隨著構(gòu)建現(xiàn)代前端應(yīng)用的需要,樣式的管理和隔離變得越來越重要,為了解決樣式?jīng)_突和管理困難的問題,CSS Modules 應(yīng)運而生,本文我們將討論如何在 Vue3 中使用 CSS Modules 實現(xiàn)樣式隔離,需要的朋友可以參考下
    2024-09-09
  • Vue3+Element?Plus實現(xiàn)動態(tài)標簽頁以及右鍵菜單功能

    Vue3+Element?Plus實現(xiàn)動態(tài)標簽頁以及右鍵菜單功能

    這篇文章主要給大家介紹了關(guān)于Vue3+Element?Plus實現(xiàn)動態(tài)標簽頁以及右鍵菜單功能的相關(guān)資料,Vue?3和Element?Plus提供了一種簡單的方法來實現(xiàn)側(cè)邊菜單欄與標簽頁之間的聯(lián)動,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2023-09-09

最新評論

成安县| 灵寿县| 杭锦后旗| 沛县| 黄平县| 辰溪县| 山阳县| 北碚区| 若尔盖县| 广丰县| 辽宁省| 郑州市| 修武县| 孝昌县| 保山市| 且末县| 应城市| 德钦县| 阳原县| 洪雅县| 平乡县| 建水县| 牡丹江市| 达拉特旗| 班玛县| 宁武县| 阿克陶县| 肃南| 安溪县| 徐汇区| 桐柏县| 荥阳市| 涡阳县| 武城县| 普兰店市| 桑日县| 荣昌县| 溧水县| 西吉县| 平利县| 天全县|