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')
  • 最终结果

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