虚拟dom
表示真实dom的js对象,里面包含字段有标签名、标签属性、子标签的名称、文本节点
diff算法
diff算法的主要功能就是最小化的更新视图,diff算法就会对比新旧两个虚拟dom之间的变化,寻找最小化更新视图的方法。diff算法的本质是对比两个js对象的差异。
原理是:当数据改变后会厨房setter方法,进而触发dep.notify方法,然后通知到各个数据的使用方执行patch(oldynode, newvnode)方法,patch方法接受两个参数,分别是新旧虚拟dom节点。
patch方法首先会在内部判断这两个是不是同类标签,如果不是的话(就没有比对必要)直接替换即可。如果是同类标签的话,则进一步执行patchVnode方法。
patchVnode内部首先会判断新旧虚拟节点是否相等,如果相等的话(也没有比对的必要)直接return即可。 如果不相等的话,要分4种情况进行比对。比对的原则是以新虚拟节点的结果为准。
第一种情况是,新旧虚拟结点都有文本结点,则直接用新的文本节点替换旧的文本节点即可。
第二种情况是,旧的没有子节点,新的有子结点,则直接添加新的子节点即可。
第三种情况是,旧的有子节点,新的没有子结点,则直接删除旧的子节点即可。
第四种情况是,新旧都有子节点,则需要调用updateChildren方法进行下一步的判断。****
updateChildren内部只会对虚拟dom树做同级的比较吗,从而最大化的提高比对性能。同级比较时它采用的是首尾指针法,因为不管新旧虚拟节点都会有首尾两个元素,对应的是start和end。
按照①
- oldS🆚newS
- oldS🆚newE
- oldE🆚newS
- oldE🆚newE 的顺序依次比较,比较成功后会退出比较
②渲染结果新虚拟结点为准,并且比较成功后start和end点会向中间靠拢。
③当新旧两个节点中的开始节点有一个跑到结束结点右侧时,终止比较。
④如果都匹配不到,则旧虚拟DOM key值去比对新虚拟DOM的key值,如果key相同则复用,并移动到新虚拟DOM的位置