iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 4
5

https://ithelp.ithome.com.tw/upload/images/20171214/20107107apht5gUyx6.png

概述

DOM 是文檔對像模型(Document Object Model)的簡寫,在瀏覽器中我們可以使用 js 來操作 DOM,但是這樣的操作性能很差,於是 Virtual Dom 應運而生。Virtual Dom 是在 js 中模擬 DOM tree 優化 DOM 的操作。

一般來說,我們看到的 DOM 是長這樣的

<div id="myId"></div>

附上 fiddle https://jsfiddle.net/hunterliu/wcvuuvjz/1/

我們可以用 JavaScript 物件表示上例的 DOM 結構

var node = {
  tagName: 'div',
  attributes: [ { 'id': 'myId' } ],
  children: []
};

然後對這個物件操作,例如:新增一個子節點

node.children.push({
  tagName: 'div',
  attributes: [ { 'id': 'childId' } ],
  children: []
});

最後更新回真實的 DOM 上。

update(originalNode, node);

VNODE 對象

在 Vue.js 中的 Virtual DOM 就是 VNODE。
概述中的範例僅僅是一個示意,實際的 VNODE 實例包含以下屬性:

  • tag: 當前節點的標籤名(如: div, p, a 等等)。
  • data: 當前節點的數據對象
  • children: 數組類型,包含了當前節點的子節點
  • text: 當前節點的文本
  • elm: 當前 VNODE 對應的真實的 DOM 節點
  • ns: 節點的 namespace
  • context: 編譯作用域
  • functionalContext: 函數化組件的作用域
  • key: 節點的 key 屬性,用於作為節點的標識,有利於 patch 的優化
  • componentOptions: 創建組件實例時會用到的選項信息
  • child: 當前節點對應的組件實例
  • parent: 組件的佔位節點
  • raw: raw html
  • isStatic: 靜態節點的標識
  • isRootInsert: 是否作為根節點插入,被 包裹的節點,該屬性的值為 false
  • isComment: 當前節點是否是註釋節點
  • isCloned: 當前節點是否為克隆節點
  • isOnce: 當前節點是否有 v-once 指令

VNODE 分類

  • EmptyVNode: 沒有內容的註釋節點
  • TextVNode: 文本節點
  • ElementVNode: 普通元素節點
  • ComponentVNode: 組件節點
  • CloneVNode: 克隆節點,可以是以上任意類型的節點,唯一的區別在於isCloned屬性為true

以上 VNODE 對象 及 分類 截取自 https://segmentfault.com/a/1190000008291645#articleHeader4

Render Function

我們也可以透過 render 操作 Virtual DOM 來建立一個 DOM element。

<div id="app">
  ${ message }
  <my-component level="1"></my-component>
</div>
Vue.component('my-component', {
  render: function (createElement) {
    return createElement(
      'div', {},
      [
        createElement('p', 'Hello Vue 2!'),
      ]
    )
  }
});

var vm = new Vue({
  el: '#app',
  delimiters: ['${', '}'],
  data: {
    message: 'Hello Vue!'
  }
});

附上 fiddle https://jsfiddle.net/hunterliu/1jswbw2L/2/

Vue 2.0 Rendering Flow

https://ithelp.ithome.com.tw/upload/images/20171214/20107107yMvgLW6gyP.png

資料來源:Next Vue.js 2.0

說明上圖過程:

  • template 經由 parse 解析得到 AST tree (抽象語法樹,abstract syntax tree)。
  • 使用 AST 生成渲染函數 (render functions),執行渲染函數會得到 VNODE(即為上面提到的 VNODE 對象)。
  • watcher 蒐集依賴、經由 observer 對 VNODE(Virtual DOM) 做資料綁定和更新。
  • 最後 VNODE 經由 patch 後 render 為真正的 HTML。

https://ithelp.ithome.com.tw/upload/images/20171214/20107107Ip1Bmf0mrw.png

資料來源:Next Vue.js 2.0

說明上圖過程:

已經 render 過後,若綁訂的 data 有異動,則會做更新,例如:比對、重新綁定資料、更新必要的 DOM element。
Vue.js 和 React.js 的 virtual DOM 基本上皆使用 snabbdom,並做客製化,這裡有簡易版的說明。

參考資料


上一篇
用範例理解 Vue.js #3:Vue Instance & Instance Lifecycle Hooks
下一篇
用範例理解 Vue.js #5:Template Syntax
系列文
用範例理解 Vue.js30

尚未有邦友留言

立即登入留言