MVVM原理(建立虛擬DOM樹)

1.創建虛擬節點的類,這裏使用es6語法糖。

export default class VNode {
    constructor(
        // 節點類型和標籤類型的區別是什麼?
        tag, // 標籤類型,DIV,SPAN,INPUT,#text
        ele, // 對應的真實節點
        children, // 當前節點下的子節點
        text, // 當前虛擬節點的文本
        data, // VNodeData,暫時保留,暫無意義
        parent, // 父級節點
        nodeType, // 節點類型
    ) {
        this.tag = tag;
        this.ele = ele;
        this.children = children;
        this.text = text;
        this.data = data;
        this.parent = parent;
        this.nodeType = nodeType;
        this.env = {}; // 當前節點的環境變量,這個是自己設定的
        this.instructions = null; // 存放指令的
        this.template = []; // 當前節點涉及到的模板
    }
}

2.構建虛擬DOM樹並且掛載到Vue上,使用深度先搜索構建虛擬DOM樹。

import VNode from "../vnode/vnode.js";

export function initMount(Vue) {
    Vue.prototype.$mount = function (el) {
        let vm = this;
        let rootDom = document.getElementById(el);
        mount(vm, rootDom);
    }
}

export function mount(vm, ele) {
    // 進行掛載
    vm._vnode = constructVNode(vm, ele, null);
    // 進行預備渲染(簡歷渲染索引,通過模板找vnode,通過vnode找模板)
}

function constructVNode(vm, ele, parent) {
    let vnode = null;
    let children = [];
    let text = getNodeText(ele); // 不確定是否有文本,只有文本節點纔有文本
    let data = null;
    let nodeType = ele.nodeType;
    let tag = ele.nodeName;
    vnode = new VNode(tag, ele, text, data, parent, nodeType);

    // 獲取子節點
    let childs = vnode.ele.childNodes;
    // 深度優先算法DFS
    for (let i = 0; i < childs.length; i++) {
        let childNode = constructVNode(vm, childs[i], vnode);
        if (childNode instanceof VNode) { // 返回單一節點的時候
            vnode.children.push(childNode);
        } else { // 返回節點數組
            vnode.children = vnode.children.concat(childNode);
        }
    }
    return vnode;
}

function getNodeText(ele) {
    if (ele.nodeType === 3) { // 標籤類型爲#TEXT時
        return ele.nodeValue;
    } else {
        return '';
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章