zoukankan      html  css  js  c++  java
  • 将真实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>

  • 相关阅读:
    扯蛋的密码规则
    【转】mysql安全基线设置
    阿里云安全基线 记录如下 不定时更新
    解决Apache的错误日志巨大的问题以及关闭Apache web日志记录
    cms如何绑定二级域名
    宝塔面板定时/同步备份网站及数据库至FTP存储空间完整教程
    宝塔部署项目报Warning: require(): open_basedir restriction in effect的解决方案
    git学习笔记(一)—— git环境搭建
    vim学习笔记(一)—— vim安装方法
    Intel Edison学习笔记(二)—— 入门环境配置
  • 原文地址:https://www.cnblogs.com/fqh123/p/13623260.html
Copyright © 2011-2022 走看看