vue核心---虛擬dom的實現

生成dom的過程

  • 由vue模板生成虛擬dom

  • 虛擬dom轉換成真實dom渲染到html頁面

代碼實現

  • 要實現的真實dom
<div id="box">
    <p class="red">hello<span>world</span></p>
    <hr />
</div>
  • 虛擬dom (在此省略template模板編譯的過程,直接手動創建)
let vNode = h('div', { //生成js對象虛擬節點
	id: 'box'
}, [ 
	h('p', {
		class: 'red'
	}, [
		h('span', {}, [h('', {}, ['world'])])
	]),
	h('hr', {}, [])
])

結果:

生成虛擬dom的h函數的實現

function h(tagName, props = {}, children = []) { //生成虛擬dom
	if (!(this instanceof h)) { 
		return new h(tagName, props, children)
	}
	this.tagName = tagName //添加屬性
	this.props = props
	this.children = children
	// this.key = key++
}
  • 將虛擬dom轉化成正式的dom
function createElements(vNode) { //創建成實際的dom
	let el
	if (vNode.tagName){ //爲標籤就創建標籤節點
		el = document.createElement(vNode.tagName)
	} else {//否則創建文本節點
		el = document.createTextNode(vNode.children)
	}

	for (attr in vNode.props) {   //遍歷屬性創建屬性
		el.setAttribute(attr, vNode.props[attr])
	}
	vNode.children.forEach((item) => { //
		// console.log(item)
		if (item.children) {//如果子節點不爲空就遞歸創建
			let children = createElements(item)
			el.appendChild(children) //將每次創建的子節添加到父節點中
		}
	})
	return el
}
  • 將真實dom渲染到頁面指定容器中,寫一個簡單render函數
let vDom = createElements(vNode)
function render(vDom, dom) { //將創建的dom添加到指定的容器中
    document.querySelector(dom).appendChild(vDom)
}
render(vDom, '#app')
  • 最終結果

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