重点:虚拟dom是虚拟的,只在概念里面存在,真实的是一个ast语法树
<template>
<div id="123">
<p><span class="234"></span></p>
<p>111</p>
</div>
</template>以上代码解析为对象形式展示
var virtualDom = {
dom:'div',
props:{
id:123
},
children:[
{
dom:"p", props:{},
children:[
dom:"span",
props:{
class:'234'
},
children:[]
] },
{
dom:"p",
props:{},
text:'111',
children:[]
} ]
}diff算法比对流程
patchVnode(oldVnode,vnode){
//获取真实dom
const el = vnode.el = oldVnode.el
//分别拿出旧节点的子元素和新节点的子元素
let i, oldCh = oldVnode.children, ch = vnode.children
//如果两个节点相同,没有发生更新的话,不做任何事情
if (oldVnode === vnode) return
//接下来分4种情况:只有文字节点,删除了子元素,增加子元素,子元素变动
//判断旧的dom文字是否为空,新的dom文字是否为空,新旧dom的文字是否相同
if (oldVnode.text !== null && vnode.text !== null && oldVnode.text !== vnode.text) {
//单纯的文字节点
//更新文字内容
api.setTextContent(el, vnode.text)
} else {
//更新dom
updateEl()
//判断新旧节点子元素是否存在,是否发生改变
if (oldCh && ch && oldCh !== ch) {
//存在,并且发送变化
//更新子元素
updateChildren()
} else if (ch) {
//新节点有子元素,老节点没有子元素,所以需要创建新的子元素
createEl(vnode)
} else if (oldCh) {
// 新节点没有子元素,老节点有子元素,所以需要删除老节点的子元素
api.removeChildren(el)
}
}
}