首頁 > web前端 > js教程 > 主體

從頭開始設計虛擬 DOM:逐步指南

Mary-Kate Olsen
發布: 2024-10-20 20:38:30
原創
276 人瀏覽過

Designing a Virtual DOM from Scratch: A Step-by-Step Guide

如果您聽說過 React 或 Vue 等前端庫,您可能遇到過術語 虛擬 DOM。虛擬 DOM 是一個聰明的概念,它可以透過提高 DOM 更新效率來幫助加快 Web 開發速度。

在本指南中,我們將詳細介紹如何使用通用的類似程式碼的步驟從頭開始實作簡單的虛擬 DOM。

什麼是虛擬 DOM?

虛擬 DOM 只是真實 DOM(網頁結構)的輕量級記憶體表示。我們不是直接更新真實 DOM(這很慢),而是先對虛擬 DOM 進行更改,弄清楚發生了什麼變化,然後只更新真實 DOM 中需要更新的部分。這可以節省時間並使您的應用程式運行得更快!


第 1 步:將虛擬 DOM 表示為樹

將網頁的結構想像成一棵樹,其中每個元素(如

)都是樹中的一個「節點」。 虛擬 DOM 節點 是一個代表這些元素之一的小物件。

這是一個例子:

Virtual DOM Node:
{
  type: 'div',
  props: { id: 'container' },  // attributes like id, class, etc.
  children: [                 // children inside this element
    {
      type: 'p',              // a <p> tag (paragraph)
      props: {},
      children: ['Hello, world!']  // text inside the <p> tag
    }
  ]
}
登入後複製
登入後複製

這描述了一個

;帶有 id="container" 的元素,其中包含

;帶有文字 「你好,世界!」.

的元素

要點:

  • 每個節點都有一個型別(例如 div、p)。
  • 它可以有 props(如 id、class 等)。
  • 它還有可以是其他元素或文字的子元素。

第二步:將虛擬 DOM 渲染到真實 DOM

現在我們有了虛擬 DOM,我們需要一種方法將其轉換為頁面上的真實 HTML。

讓我們寫一個名為 render 的函數,它接收虛擬 DOM 節點並將其轉換為實際的 HTML 元素。

function render(vNode) {
  // 1. Create a real element based on the Virtual DOM type (e.g., div, p).
  const element = document.createElement(vNode.type);

  // 2. Apply any attributes (props) like id, class, etc.
  for (const [key, value] of Object.entries(vNode.props)) {
    element.setAttribute(key, value);
  }

  // 3. Process the children of this Virtual DOM node.
  vNode.children.forEach(child => {
    if (typeof child === 'string') {
      // If the child is just text, create a text node.
      element.appendChild(document.createTextNode(child));
    } else {
      // If the child is another Virtual DOM node, recursively render it.
      element.appendChild(render(child));
    }
  });

  return element;  // Return the real DOM element.
}
登入後複製
登入後複製

這裡發生了什麼事?

  • 我們建立一個元素 (document.createElement(vNode.type))。
  • 我們新增任何屬性(如 id、class 等)。
  • 我們透過新增文字或在每個子元素上再次呼叫渲染來處理子元素(文字或其他元素)。

第 3 步:比較(差異)新舊虛擬 DOM

當我們的網頁應用程式發生某些變化(例如文字或元素的樣式)時,我們會建立一個新的虛擬 DOM。但在更新真實 DOM 之前,我們需要比較舊 Virtual DOM新 Virtual DOM 來找出發生了什麼變化。這稱為「比較」

讓我們建立一個比較兩個虛擬 DOM 的函數:

Virtual DOM Node:
{
  type: 'div',
  props: { id: 'container' },  // attributes like id, class, etc.
  children: [                 // children inside this element
    {
      type: 'p',              // a <p> tag (paragraph)
      props: {},
      children: ['Hello, world!']  // text inside the <p> tag
    }
  ]
}
登入後複製
登入後複製

差異如何運作:

  • 節點類型變更:如果元素類型變更(例如將
    變更為

    ),我們會將其標記為替換。

  • 文字更改:如果內部文字發生更改,我們會更新文字。
  • 屬性和子元素:我們檢查元素的任何屬性(props)或子元素是否已更改。

  • 第 4 步:修補真實 DOM

    一旦我們知道發生了什麼變化,我們就需要將這些變更套用到真實的 DOM 上。我們將此過程稱為修補

    修補功能的外觀如下:

    function render(vNode) {
      // 1. Create a real element based on the Virtual DOM type (e.g., div, p).
      const element = document.createElement(vNode.type);
    
      // 2. Apply any attributes (props) like id, class, etc.
      for (const [key, value] of Object.entries(vNode.props)) {
        element.setAttribute(key, value);
      }
    
      // 3. Process the children of this Virtual DOM node.
      vNode.children.forEach(child => {
        if (typeof child === 'string') {
          // If the child is just text, create a text node.
          element.appendChild(document.createTextNode(child));
        } else {
          // If the child is another Virtual DOM node, recursively render it.
          element.appendChild(render(child));
        }
      });
    
      return element;  // Return the real DOM element.
    }
    
    登入後複製
    登入後複製

    關鍵操作:

    • 替換: 將一個元素完全替換為另一個元素。
    • 文字:更新元素內的文字。
    • 更新:根據變更更新屬性和子項目。

    虛擬 DOM 流程總結:

    1. 虛擬 DOM 樹: 我們建立一個樹狀結構,表示網頁上的元素及其層次結構。
    2. 渲染為真實 DOM: 此虛擬 DOM 被轉換為真實的 HTML 元素並放置在頁面上。
    3. 比較演算法:當發生變化時,我們將舊的 Virtual DOM 與新的進行比較以找出差異。
    4. 修補真實 DOM: 以最有效的方式將這些變更套用到真實 DOM。

    最後的想法

    虛擬 DOM 是一個強大的工具,它透過減少對真實 DOM 的不必要的變更來更快地更新使用者介面。透過實現虛擬 DOM,我們可以優化 Web 應用程式更新和渲染元素的方式,從而帶來更快、更流暢的使用者體驗。

    這是虛擬 DOM 概念的基本實現,但您現在已經有了理解 React 等框架如何使用它的基礎!

以上是從頭開始設計虛擬 DOM:逐步指南的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門推薦
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!