MVVM的核心之一就是虛擬dom樹,我們這一章節就先構建一個虛擬dom樹
首先我們需要創建一個VNode的類
// 當前類的位置是src/vnode/index.js?
export default class VNode{constructor(tag, // 標簽名稱(英文大寫)ele, // 對應真實節點children, // 子節點text, // 文本內容data, // 節點數據parent, // 父節點nodeType, // 節點類型key // 節點key) {this.tag = tag;this.ele = ele;this.children = children;this.text = text;this.data = data;this.parent = parent;this.nodeType = nodeType;this.key = key;this.env = {} // 環境變量this.instructions = [] // 指令this.template = [] // 當前節點的模板 }
}
第二步:構建虛擬dom
?構建虛擬dom樹的操作我們放在mount事件里面,現在需要創建mount.js
import VNode from '../vnode/index'/*** 給MiniVue添加掛載方法* @param {*} MiniVue */
export function initMount(MiniVue) {MiniVue.prototype.$mount = function (el) {let root = document.getElementById(el)mount(this, root)}
}/*** 實現mount事件* @param {*} vm * @param {*} el */
function mount(vm, el) {console.log('開始掛載')// 構建虛擬Domvm._vnode = constructVnode(vm, el, parent)// 預備渲染
}function constructVnode(vm, el, parent) {let vnode = null;const tag = el.nodeNameconst text = el.textContent.trim()const data = {}const nodeType = el.nodeTypeconst key = ""vnode = new VNode(tag, el, [], text, data, parent, nodeType, key)// 遞歸構建子節點vnode.ele.childNodes.forEach(child => {const childNodes = constructVnode(vm, child, vnode)if(childNodes instanceof Array) {vnode.children.push(...childNodes)} else {vnode.children.push(childNodes)}})return vnode
}/*** 獲取節點的文本數據(文本節點)* @param {*} el */
function getNodeText(el) {return el.nodeType === 3 ? el.textContent.trim() : ''
}
init方法里面執行當前mount
我們在瀏覽器里面可以看到當前構建的虛擬dom樹
本章總結:
1.創建虛擬DOM的類
2.給原型添加mount方法,通過根節點el構建虛擬dom
3.構建dom時,使用深度優先搜索算法(反復調用本身方法),獲取子節點