Open
Description
DEMO:https://jsbin.com/lekajaw/edit?html,output
TODO 正在热火朝天更新中,欢迎催更~
核心原理
虚拟节点vnode:
vnode = {
"tag": "div",
"children": [
{
"text": "hi, Vue.js"
}
],
}
渲染出真实DOM HTML:
<div>hi, Vue.js</div>
- 调用
vm.patch(vm.$el, vnode)
方法,传入旧节点和新节点作为参数。第一次渲染的旧节点是一个空的虚拟节点:emptyNodeAt(elm)
。 - 对新旧节点进行diff比较:DEMO 中为了简化逻辑,没有涉及,TODO: 专题研究。
- 调用
nodeOps.createElement(tag, vnode)
,基于tag等属性,将虚拟节点转化为真实DOM,赋值给vnode.elm
。 - 对
children
属性中的子元素,进行遍历,对每个子元素调用this.createElm()
递归生成真实DOM,底层基于document.createTextNode(text)
等原生DOM API实现。 - 调用
insert(parentElm, vnode.elm, refElm);
,将生成的子元素真实DOM树,插入到父元素中;将新节点完整的真实DOM树,插入到body
元素中。底层基于parentNode.insertBefore
,node.appendChild(child)
等原生DOM API实现。 - 最后,调用
this.removeVnodes(oldVnode)
,删除旧节点对应的真实DOM,基于原生DOM API:node.removeChild(child);
实现。
Metadata
Assignees
Labels
No labels