Vue模版转化成视图过程
- vue.js将template模版编译,转换成渲染函数(render),每执行一个渲染函数就会生成一个虚拟DOM
- patch:将vnode渲染成真实的DOM。通过对比新旧节点,找到需要更新的,更新到真实的DOM视图。
虚拟DOM的好处
减少DOM操作,提高渲染速度,提升性能。
patch
-
patch方法中,对oldVnode和vnode对比
-
当oldVnode不存在时,就用createElm创建新的节点
-
否则用sameVnode()方法对两个参数进行属性对比,patch核心——diff算法
-
通过diff算法判断哪些节点发生变化,更新视图。
function patch (oldVnode, vnode, hydrating, removeOnly, parentElm, refElm) { // 当oldVnode不存在时 if (isUndef(oldVnode)) { // 创建新的节点 createElm(vnode, insertedVnodeQueue, parentElm, refElm) } else { const isRealElement = isDef(oldVnode.nodeType) if (!isRealElement && sameVnode(oldVnode, vnode)) { // patch existing root node // 对oldVnode和vnode进行diff,并对oldVnode打patch patchVnode(oldVnode, vnode, insertedVnodeQueue, removeOnly) } } }
function sameVnode (a, b) { return ( a.key === b.key && a.tag === b.tag && a.isComment === b.isComment && isDef(a.data) === isDef(b.data) && sameInputType(a, b) ) }
vnode的属性:
-
tag:属性即这个vnode的标签属性
-
data:属性包含了最后渲染成真实dom节点后,节点上的class,attribute,style以及绑定的事件
-
children:属性是vnode的子节点
-
text:属性是文本属性
-
elm:属性为这个vnode对应的真实dom节点
-
key:属性是vnode的标记,在diff过程中可以提高diff的效率。
{ tag: 'div' data: { id: 'app', class: 'page-box' }, children: [ { tag: 'p', text: 'this is demo' } ] }
映射后呈现的是:
<div id="app" class="page-box"> <p>this is demo</p> </div>