1. 程式人生 > >Vue雙向繫結原理(一)文件片段DocumentFragment

Vue雙向繫結原理(一)文件片段DocumentFragment

DocumentFragment介紹

JavaScript有以下幾種建立節點的方式:

  • createAttribute(name):       用指定名稱name建立特性節點
  • createComment(text):        建立帶文字text的註釋節點
  • createElement(tagname):       建立標籤名為tagname的節點
  • createTextNode(text):        建立包含文字text的文字節點
  • createDocumentFragment():     建立文件碎片節點

前幾個比較簡單,我們也順便簡單說一下:

createAttribute(name)


用於建立一個指定名稱name的屬性,例如:

var att=document.createAttribute("class");
att.value="democlass";
//給h1標籤添加了一個`class="democlass"` 的屬性
document.getElementsByTagName("H1")[0].setAttributeNode(att);

createComment(text)
用於建立一個帶文字text的HTML註釋節點,例如:

var c=document.createComment("My personal comments");
document.body.appendChild(c);
//結果為  <!-- My personal comments -->

createElement(tagname)
用於建立一個指定名稱的HTML元素。這個是最常用的了。例如:

//建立一個<p></p>元素
var p=document.createElement("p");

createTextNode(text)
用於建立一個文字為text的文字節點,常跟createElement配合使用。例如:

var h=document.createElement("H1");
var t=document.createTextNode("Hello World");
h.appendChild(t);

上邊幾個方法用於建立節點,都非常簡單。當我們更新少量dom節點的時候,可以建立他們然後直接appendChild()插入DOM樹。但是如果我們要建立大量節點的時候,每次都建立再插入,會呼叫很多次appendChild()方法,會非常浪費效能。為了解決這個問題,就有了documentFragmeng文件片段,可以先把這些建立的元素放入文件片段,然後在把文件片段插入DOM樹,這樣就只會呼叫一次appendChild()方法了。

createDocumentFragment()
用於建立一個文件片段作為容器,其中可以包含多個dom節點。這裡有兩點需要特別注意的地方:

  1. 當把文件片段插入DOM樹的時候,只會把它的子節點插進去,它作為容器本身是不會進入DOM樹的。
  2. 當把DOM樹種的節點插入文件片段的時候,這些節點,會真的從DOM樹種消失。我們也把這個過程叫做劫持。

在Vue中的作用

上邊說清楚了documentFragment是幹嘛的,現在說說他在vue中的作用。

每個vue例項都有一個根元素id的屬性el,Vue物件通過它來找到要渲染的部分。之後使用createDocumentFragment()方法建立一個documentFragment,遍歷根元素的所有子元素,依次劫持並插入文件片段,將根元素掏空。然後執行Vue的編譯:遍歷documentFragment中的節點,對其中的v-for,v-text等屬性進行相應的處理。最後,把編譯完成後的documentFragment還給根元素。

這也就是為什麼,我們寫在模板中的HTML,有v-for,v-model等屬性,而實際頁面F12之後卻沒有,因為那是Vue編譯之後返回的結果。