3. diff算法不同
传统Diff算法是循环递归每一个节点:
传统diff
如上图所示,从左侧a节点依次进行对比:a->d
、a->e
、a->b
、a->a
、a->c
, 剩下的其他节点也是与右侧树每个节点进行对比。
将两颗树中所有的节点一一对比需要
O(n²)
的复杂度,在对比过程中发现旧节点在新的树中未找到,那么就需要把旧节点删除,删除一棵树的一个节点(找到一个合适的节点放到被删除的位置)的时间复杂度为O(n)
,同理添加新节点的复杂度也是O(n)
,合起来diff两个树的复杂度就是O(n³)
传统Diff算法复杂度太高, vue2.x加入了 Virtual Dom
和react拥有相同的diff优化原则(将算法复杂度降为O(n)
)。
两者流程思路上是类似的:
- 不同的组件产生不同的 DOM 结构。当type不相同时,对应DOM操作就是直接销毁老的DOM,创建新的DOM。
- 同一层次的一组子节点,可以通过唯一的 key 区分。
网络上看到一张图挺形象的图:
但是在源码实现上又完全不同:
React的Diff算法核心实现
图片.png
-
react首先对新集合进行遍历,
for( name in nextChildren)
。 -
通过唯一key来判断老集合中是否存在相同的节点。如果没有的话创建
-
如果有的话,
if (preChild === nextChild )
- 会将节点在新集合中的位置和在老集合中lastIndex进行比较
- 如果
if (child._mountIndex < lastIndex)
进行移动操作,否则不进行移动操作。
-
如果遍历的过程中,发现在新集合中没有,但在老集合中有的节点,会进行删除操作
Vue的Diff算法核心实现
updateChildren
是vue diff的核心, 过程可以概括为:
旧children
和新children
各有两个头尾的变量StartIdx
和EndIdx
,它们的2个变量相互比较,一共有4种比较方式。- 如果4种比较都没匹配,如果设置了key,就会用key进行比较,在比较的过程中,变量会往中间靠,一旦
StartIdx>EndIdx
表明旧children
和新children
至少有一个已经遍历完了,就会结束比较。
可以用下图来描述在一次比较过程中四个步骤:
图片.png
Vue2的核心Diff算法采用了双端比较的算法,同时从新旧children的两端开始进行比较,借助key值找到可复用的节点,再进行相关操作。相比React的Diff算法,同样情况下可以减少移动节点次数,减少不必要的性能损耗,更加的优雅。
4. 响应式原理不同
Vue
- Vue依赖收集,自动优化,数据可变。
- Vue递归监听data的所有属性,直接修改。
- 当数据改变时,自动找到引用组件重新渲染。
React
React基于状态机,手动优化,数据不可变,需要setState
驱动新的state替换老的state。当数据改变时,以组件为根目录,默认全部重新渲染, 所以 React 中会需要 shouldComponentUpdate
这个生命周期函数方法来进行控制
5. 其他不同点
除了上面的四个点外,细数还有很多不同点的, 比如api的差异也挺大的,Vue为了更加简单易用,引入了指令、filter等概念以及大量的option API,比如 watch
、computed
等都是非常好用的。
而React的API比较少, 如果你的JavaScript基础比较好,上手也是比较容易的
当然如果你看过二者的源码,也可以说说二者源码的不同点。这里抛出它们的源码编译过程图,方便你更好的阅读源码。
Vue源码编译过程图:
React源码编译过程图:
React源码编译过程图
以上就是关于Vue和React的区别
讲解, 当面试官问到这个问题时,重点在于分析思路, 抓住要点去扩展。最后我们还可以谈谈未来发展趋势,其实随着Vue3的更新,和React在使用上相似度越来越高, 其实对于开发者来说挺好的, 上手一个框架后再学另一个,学习成本就会有所降低。
对象篇
![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy
真题解析、进阶学习笔记、最新讲解视频、实战项目源码、学习路线大纲
详情关注公中号【编程进阶路】
82MTY4MzU2LWU5ZGY5NGRhODZhZGZjNjY?x-oss-process=image/format,png)
模块化编程-自研模块加载器