首先开宗明义,为什么要用虚拟DOM?
理论上来讲,任何状态改变后,我们完全可以粗暴的根据当前的状态,生成对应的dom,就像jquery时代那样。但是设想一个场景:有一个ul下面绑着是个li标签。我们可能只是改变了其中的一个li,就是说此时,我们只需要更新那个变化了的li即可,而不需要费劲的旧dom全删了然后再一个个重新创建一遍。
虚拟DOM就是为了解决这个问题,本质上做了两件事情:

    1. 提供与真实dom节点对应的虚拟节点vnode(就是一个对象)
    1. 每次状态变化后,生成新的vnode,然后通过算法对新旧vnode对比,找出变化了的更新即可。
      重在性能优化,这也是为什么这些框架如此流行。

那么具体,什么是虚拟DOM(Vnode)?
DOM元素有元素节点(div)、文本节点(text)、注释节点等。vnode实际上就是这些节点的ADT(抽象数据类型)。
举例解释:

<p>asdasdasd</p>
const vnode = {
  tag: 'p',
  data: {...} // 比如class、style等
  children: [...], // 儿子节点
  ....
}

// 注释节点
{
  text: '注释节点',
  isComment: true
}


// 文本节点
{
  text: '一段文本'
}
...
...

vnode就是一个数据结构(对象),这个对象通过tag、text、children等属性来描述实例化的vnode。仅此而已。
至此我们明白了虚拟DOM和真实DOM之间的映射关系,完成了第一步.下面将会介绍重点中的重点: 找出变化的patch过程