根据node节点生成VNode以及解析成node节点

  • 根据node节点来生成一个VNode(vue中是是用字符串模版进行ast抽象树在进行VNode生成)
    /** 虚拟 DOM 构造函数 */
class VNode {
    constructor(tag, data, value, type) {
        this.tag = tag && tag.toLowerCase();
        this.data = data;
        this.value = value;
        this.type = type;
        this.children = [];
    }

    appendChild(vnode) {
        this.children.push(vnode);
    }
}
/**根据node生成一个虚拟DOM树 */
function getVNode(node) {
    let _vnode = null;
    let nodeType = node.nodeType;
    if (nodeType === 3) {
        _vnode = new VNode(undefined, undefined, node.nodeValue, nodeType);
    } else if (nodeType === 1) {
        // 元素
        let nodeName = node.nodeName;
        let attrs = node.attributes; // attrs[ i ] 属性节点 ( nodeType == 2 )
        let attr_obj = {};
        for (let i = 0; i < attrs.length; i++) {
            attr_obj[attrs[i].nodeName] = attrs[i].nodeValue;
        }
        _vnode = new VNode(nodeName, attr_obj, undefined, nodeType);
        // 考虑 node 的子元素
        let childNodes = node.childNodes;
        for (let i = 0; i < childNodes.length; i++) {
            _vnode.appendChild(getVNode(childNodes[i])); // 递归
        }
    }
    return _vnode;
}
  • 根据VNode进行生成node
    /**将vnode转成node */
function parseNode(vnode) {
    let type = vnode.type;
    let _node = null;
    if (type === 3) {
        return document.createTextNode(vnode.value);
    } else if (type === 1) {
        _node = document.createElement(vnode.tag);
        let attrs = vnode.data;
        Object.keys(attrs).forEach(key => {
            _node.setAttribute(key, attrs[key]);
        });

        let childrenVNode = vnode.children
        if (childrenVNode) {
            childrenVNode.forEach(sub => {
                _node.appendChild(parseNode(sub));
            });
        }
        return _node;
    }
}
posted @ 2020-05-16 15:40  Devin_n  阅读(1742)  评论(0编辑  收藏  举报