1. 程式人生 > 實用技巧 >將真實DOM轉換為虛擬DOM

將真實DOM轉換為虛擬DOM

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
    
</style>
</head>
<body>

    <div id="root" class="tt">
        <
div title="tt1">hello1</div> <div title="tt2">hello2</div> <div title="tt3">hello3</div> <ul> <li>1</li> <li>2</li> <li>3</li> </ul> </div> <script
> // 用記憶體去表述DOM // 將真實DOM轉化為虛擬DOM // <div /> => {tag:'div'} 元素轉化 // 文字節點 => {tag:undefined,value:'文字節點'} 文字節點轉化 // <div title="1" class="c" /> => { tag:'div',data:{ title:'1',class:"c" } } 多屬性轉化 // <div><div /></div> => {tag:'div',children:[{ tag:'div' }]}
// 用建構函式來 進行以上轉換 // 這一次我們用class語法 class VNode { // 建構函式 constructor( tag,data,value,type ){ // tag:用來表述 標籤 data:用來描述屬性 value:用來描述文字 type:用來描述型別 this.tag = tag && tag.toLowerCase();//文字節點時 tagName是undefined this.data = data; this.value = value; this.type = type; this.children = []; } appendChild( vnode ){ this.children.push( vnode ); } } /** 利用遞迴 來遍歷DOM元素 生成虛擬DOM Vue中的原始碼使用 棧結構 ,使用棧儲存 父元素來實現遞迴生成 */ function getVNode( node ){ let nodeType = node.nodeType; let _vnode = null; if( nodeType === 1){ // 元素 let nodeName = node.nodeName;//元素名 let attrs = node.attributes;//屬性 偽陣列 let _attrObj = {}; for(let i=0;i<attrs.length;i++){//attrs[ i ] 屬性節點(nodeType == 2) 是物件 _attrObj[ attrs[ i ].nodeName ] = attrs[ i ].nodeValue; } _vnode = new VNode( nodeName,_attrObj,undefined,nodeType); // 考慮node的子元素 let childNodes = node.childNodes; for(let i = 0;i<childNodes.length;i++){ _vnode.appendChild( getVNode( childNodes[ i ] ) );//遞迴 } }else if( nodeType === 3 ){ // 文字節點 _vnode = new VNode( undefined,undefined,node.nodeValue,nodeType); } return _vnode; } let root = document.querySelector("#root"); let vroot = getVNode ( root ); console.log(vroot); </script> </body> </html>