Vue与React的爱恨情仇

139 阅读6分钟

Vue与React区别及联系

作为前端界几乎是必会的两大框架,Vue与React的相爱相杀从之前开始就没有停止;两大框架也都有自己的优缺点和亮点。这次我就来总结一下两款框架的异同吧!

Vue介绍

Vue 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与[现代化的工具链]以及各种[支持类库]结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

React介绍

React 是一个声明式,高效且灵活的用于构建用户界面的 JavaScript 库。使用 React 可以将一些简短、独立的代码片段组合成复杂的 UI 界面,这些代码片段被称作“组件”

上面的介绍分别来自Vue官网与React官网,可以看出来介绍还是有很大不同的。Vue主张自底向上逐层应用,还便于与第三方库整合;而React则主要提了一下组件化开发

相同点

组件化开发

用过Vue和React的人可能都有组件化开发的经历吧,在这两大框架中,每一个页面,页面中的某一部分甚至是一个按钮都可以是一个组件。这些大大小小的组件构建成了一个复杂的项目体系。那为什么要组件化开发呢?首先将某个控件开发成组件可以有效提升代码复用性,降低代码量;其次可以将项目的不同模块之间解耦,如果像传统那样将整个系统做成一个应用,在后期迭代维护的时候就会特别麻烦,可能改一个地方影响其他地方,牵一发而动全身;

单向数据流

React和Vue里都遵循着单向数据流的概念,单向数据流指父组件向子组件传递数据时,子组件无权修改父组件传递的数据,只能通知父组件修改。这样做的目的主要是避免一个父子组件向多个子组件传递了数据,其中一个子组件修改后可能会触发链式反应,使组件间的数据变化难以理解,单项数据流解决了数据之间的耦合,使代码变得易于调试。

虚拟DOM

React与Vue,内部都是将模板转化成虚拟DOM处理好之后,再转化成真实DOM挂载到根元素上。这样做是因为,操作真实DOM是非常耗费性能的,将其转化为对象形式的虚拟DOM进行操作不仅可以有效提升性能,还能实现跨平台的开发。

Diff

两者都使用Diff算法来对比新生成的节点树和老节点树进行比较,最大程度的复用老节点,获取最小的更新,提升性能

不同点

写法(上手难度)

Vue上手难度比较低(降低了前端开发的门槛),因为采用的还是前端三剑客的写法,基本具有一点前端基础的同学就可以上手了,这可能与尤雨溪是个人开发者有关系。但React由于采用JSX的写法进行函数式编程,本质上就是在写JS,需要使用者具有很强的JS功底。

响应式原理不同

Vue

Vue采用的是订阅者-观察者设计模式,递归进行状态监听和依赖收集,当其中某个属性状态改变时,便可以去通知对应的订阅者进行更新。Vue2使用的是Object.defineProperty这个API进行改写属性的getter和setter,这样有个弊端就是无法监听到属性的新增和修改,数组也无法进行监听(Vue2重写了数组的部分方法) Vue3中采用了Proxy劫持了整个对象,这样做的好处是实现了属性的新增和删除,并且也支持监听数组。而且其还做了优化,就是当有对象嵌套时,当你用到其中的对象时,它才会去劫持监听,实现了速度的提升

React

React基于状态机制,手动优化,数据其实是不可变的,需要setState驱动新的State替换老State,而且使用这个API有很多的坑点,比如它是异步改变数据。当数据改变时,以组件为根,默认全部更新渲染。

优化方式不同

Vue底层已经实现了最优的更新渲染优化,但是React必须使用户手动实现,例如说shouldComponentUpdate等,如果遇到逻辑复杂的优化时,便会显得整个组件冗余,不宜阅读与维护

Diff

两者优化思维类似,都是同层节点比较,使复杂度由n^3降低为n。

为什么对比两个树时间复杂度为n^3呢?

因为对比两棵树节点的复杂度为n^2,而删除一个节点后,将新节点移动添加到此位置的复杂度为n

Vue和React都引入了key,用于对比节点的变化,最大程度复用节点。Vue使用双向链表,边对比边更新;而React是对比时为每个节点打上删除或者复用等的标记,在对比完后同意更新

事件绑定机制不同

Vue事件机制

Vue底层主要采用web官方API进行绑定,父子组件的通信使用自定义事件

Vue3中采用了事件监听器缓存,同一个事件会生成内联函数缓存起来进行复用

React事件机制

React自己实现了一套事件机制,将所有事件同意冒泡到doucument监听,然后合成事件触发,这样不仅减少了内存消耗,还便于在组件销毁时同意移除组件绑定的事件;触发的事件并不是浏览器原生事件,而是React自己实现的合成事件,如果不想要事件冒泡,必须调用preventDefault

React合成事件的好处
  • 便于跨浏览器开发,解决各个浏览器的兼容问题
  • 优化性能,如果我们有很多事件需要监听,就会创建很多事件,消耗内存;而React有专门的事件池控制事件的创建和销毁,还可以进行事件复用