将真实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>

原文地址:https://www.cnblogs.com/fqh123/p/13623260.html