大家好,我是沐华。最近部门招人,捞了一批简历至少都是5年以上的前端来面试,其中不乏360的,腾讯的,简历上写的基本都是熟练使用 Vue2
、Vue3
、React
并阅读源码对其实现原理有自己的理解,实际问起来却不免让人唏嘘
比如:既然两个框架都用过,那能说一下你觉得这俩有什么区别吗?
毕竟是两个框架,不像两个 API
,要说细节上的区别就太多太多了,可能能聊几个小时都聊不完,所以你给自己的定位是什么呢?
说说 Vue 和 React 的区别
青铜级
只要真正了解一些,或者用过两个框架开发,就一定能说上来的一些语法层面:
Vue API
多,React API
少Vue
双向绑定,修改数据自动更新视图,而React
单向数据流,需要手动setState
Vue template
结构表现分离,React
用jsx
结构表现融合,html/css都可以写到js里- 都可以通过
props
进行父子组件数据传递,只是Vue props
要声明,React
不用声明可能直接使用 Vue
可以用插槽,React
是万物皆可props
Vue2
利用基本都是Mixin
,React
可以用高阶函数、自定义hook
实现Vue
的frgments
、hook
到Vue3
才有,Vue
还有丰富的指令,过滤器
都支持服务端渲染,都有虚拟 DOM
,数据驱动,组件化开发,响应式,组件通信,生命周期,Diff
,都有状态管理 Vuex/Pinia
、Redux/Mobx
,等等等等....
白银级
- 可以加一些偏感受方面的,比如:
React
官方只关注底层,上层应用解决方案都交给社区,所以 React
生态体系丰富,社区强,而且每次更新改动小等 等,而 Vue
是由官方主导开发和维护,生态没那么丰富,虽然上手比 React
简单一些,但每次更新堪称破土重来,改的倒是潇洒得很,这就注定我们学习成本大大增加,并不能做到学习一次就可以一直使用这个框架,1.0 改版 2.0 需要重新学习一遍,2.0 改版 3.0 又要学习一遍,甚至 3.0 到 3.2 都要重学一部分,有些程序员到了 35 退休不是不想干,也是学不动了吧。像是需要记的 API
,React
就那么几个,剩下的自己去写就行了,Vue
虽然在代码维护上有一定优势,可是它的 API
就多得多了,而且还分版本,比如 Vue2
有过滤器,Vue3
却没了,不仅要多记很多 API
和自定义指令,还需要对自己所学的 API
根据版本进行选择使用,感觉不怎么严谨
- 也可以将青铜级上面的某些点展开说一下细节,比如:
组件化:
Vue2
组件说白了就是一个挂满一堆东西的Vue
核心类,通过new Vue()
拿到实例。就是说Vue
组件的script
导出的是一个挂满各种options
的纯对象而已,所以options API
的this
指向Vue
实例,这对我们开发者来说是不透明的,需要文档才能知道上面一堆this.$xxx
是干嘛用的,而且Vue
的插件也都是基于Vue
原型类基础上的,Vue.install
挂到Vue
实例上去嘛,以保证和第三方库的Vue
调的是同一个Vue
对象- 而
React
则比较简单,直接定义render
函数生成vnode
,里面通过四个组件类包装vnode
而已,不同类型的vnode
用相对应的组件类处理,就像责任划分一样,各自只负责自己的。而且React
类组件都是继承于React.Component
类,它的this
指向我们自定义的类,可以说对我们开发者来说是透明的
hook:
React hook
是根据调用顺序来确定下一次重新渲染时的state
是来源于哪个,所以有一些限制,比如不能在循环/条件判断/嵌套函数里使用,而且必须在函数最顶层调用hook
等Vue3 hook
是基于响应式实现的,它是声明在setup
里,一次组件实例化只调用一次setup
,而React
每次重新渲染都要重新调用,性能上自然不言而喻,而且可以在循环/条件判断/嵌套函数里使用,并且正因为是基于响应式实现的,还自动实现了依赖收集,而React
需要手动传入依赖等
等等...
黄金级
起码得深入源码吧,比如:
响应式:
Vue2
响应式的特点就是依赖收集,数据可变,自动派发更新,初始化时通过Object.defineProperty
递归劫持data
所有属性添加getter
/setter
,触发getter
的时候进行依赖收集,修改时触发etter
自动派发更新找到引用组件重新渲染Vue3
响应式使用原生Proxy
重构了响应式,一是proxy
不存在响应式存在的缺陷,二是性能更好,不仅支持更多的数据结构,而且不再一开始递归劫持对象属性,而是代理第一层对象本身。运行时才递归,用到才代理,用effect
副作用来代替Vue2
里的watcher
,用一个依赖管理中心trackMap
来统一管理依赖代替Vue2
中的Dep
,这样也不需要维护特别多的依赖关系,性能上取得很大进步- 相比
Vue
的自动化,eact
则是基于状态,单向数据流,数据不可变,需要手动setState
来更新,而且当数据改变时会以组件根为目录,默认全部重新渲染整个组件树,只能额外用pureComponent
/shouldComponentUpdate
/useMemo
/useCallback
等方法来进行控制,更新粒度更大一些
Diff 算法:
Vue2
是同层比较新老vnode
,新的不存在老的存在就删除,新的存在老的不存在就创建,子节点采用双指针头对尾两端对比的方式,全量diff
,然后移动节点时通过splice
进行数组操作Vue3
是采用Map
数据结构以及动静结合的方式,在编译阶段提前标记静态节点,Diff
过程中直接跳过有静态标记的节点,并且子节点对比会使用一个source
数组来记录节点位置及最长递增子序列算法优化了对比流程,快速Diff
,需要处理的边际条件会更少React
是递归同层比较,标识差异点保存到Diff
队列保存,得到patch
树,再统一操作批量更新DOM
。Diff
总共就是移动、删除、增加三个操作,如果结构发生改变就直接卸载重新创建,如果没有则将节点在新集合中的位置和老集合中的lastIndex
进行比较是否需要移动,如果遍历过程中发现新集合没有,但老集合有就删除
钻石级
这得要脱离代码层面,上升到更加宏观的层面吧,区别摆在那里是死的,固定的,就主要看人怎么说了,比如
- 以突出核心思想和设计理念开头:
我觉得最主要就是核心思想和设计理念上的区别,React
一开始定位的就是 UI 开发的新思路,这种思想说白了就是要改变开发者,我制定规则,你们都照我的来,因为背靠大公司(facebook
),所以不缺用户,而 Vue
是尽可能降低前端开发的门槛来适应不同的开发者,让开发者怎么爽怎么来,正是因为这种设计理念上的差别对后续设计也产生了一些不可逆的影响,或者说这两框架后续架构的变化都是围绕这个来的。
- 以突出数据管理开头:
我觉得这两最主要的区别是在数据管理方式上,虽然都是数据驱动,但 Vue
是响应式的,React
是手 setState
,可以说正是因为这个对后面架构的设计都产生了一些不可逆的影响,或者说这两框架后续架构的变化都是围绕这个来的。
主要体现在这些方面:
比如 Vue
是对数据进行劫持/代理,它对监测数据的变化更加精准,动了多少数据就触发多少更新,更新粒度很小,而 React
推崇函数式,这是没办法感知数据变化的,就是说不知道什么时候应该刷新,而且即便是手动 setState
触发更新,它也也不知道哪些组件需要刷新,而是渲染整个 DOM
,说白了就是无脑刷新嘛,这样就导致性能不好,所以后面只能不断通过其他办法来避免不必要的刷新,或者优化无脑刷新的性能。当然 Vue
也不是那么完美,它实现精准刷新也是有代价的,就是需要给每个组件配置监视器,管理依赖收集和派发更新,这同样是有消耗的。且不是说性能谁好吧,我们可以对比下这两框架版本迭代可以发现,React
迭代是增加了一个个避免刷新的钩子函数或者 API
还有采用 Fiber
的架构来做时间分片也是来优化渲染的性能。而 Vue1
/Vue2
/Vue3
每个版本虽然改的东西多,但核心都是围绕响应式来优化的,所以我觉得这是这两框架之间最重要的区别
比如正是这种设计上的区别,也直接影响了 hooks
的实现和表现,React hook
底层是基于链表实现的,每次组件被 render
的时候都会按顺序执行所有 hooks
,而且正因为底层是链表,每个 hook
的 next
是指向下一个 hook
的,所以我们写代码是不能在不同的 hooks
调用里使用条件判断/函数嵌套之类的,因为这会导致执行顺序不对,从而出错。而 Vue hook
只会被注册调用一次,因为它是声明在 setup
里,一次组件实例化只调用一次 setup
,Vue
之所以能避开这些问题,主要还是得益于数据响应式,不需要链表对 hooks
进行记录,而是直接对数据代理观察,但它也有困扰的地方,就是不得不返回一个包装对象,通过 .value
获取。因为在 JS
里基础类型只有值,没有引用,或者说只存在栈里,使用完就回收了,无法追踪后续变化,自然做不到数据的代理和拦截,这算是这个设计的一个缺点吧
再比如编译优化的问题,Vue
能够做到数据劫持,再到 Vue3
动静结合的 Diff
思想也得益于它的模板语法实现了静态编译。就是能做到预编译优化,可以静态分析,在解析模板时能根据解析到的不同的标签、文本等分别执行对应的回调函数来构造 AST
,而 React
虽然 JSX
语法更加灵活,可也正是因为这样导致可以优化的地方不足,重新渲染时就是一堆递归调用 React.createElement
,无法从模板层面进行静态分析,也就做不到双向绑定,即使是很厉害的 fiber
,也是因为伤害已经造成,所以通过时间分片的优化来弥补伤害吧,因为已经无法在编译阶段进行优化了,这也是这个设计所带来的问题吧
王者级
(可以评论区讨论一下)
项目选型怎么考虑?怎么选择?
从加载速度,运行时性能来说,我觉得这两个框架综合各种场景应该是没什么质的差别的。硬要说的话,Vue
在更新时性能优化方面需要的心智负担可能会少那么一点,特别是 Vue3
,而 React
如果不注意,容易导致一些组件无用的 Diff
,但其实实际项目中真正能遇到这种性能瓶颈的也是极少数,所以(这里有两种说法):
(如果公司主要用 Vue
技术栈的话):所以总的来说我觉得 Vue
性能上会更有优势一点,特别是 Vue3
更加灵活,有很好的可扩展性,同时有更快的渲染速度和更小的打包体积。从 mixins
到 HOC
到 render props
再到 hooks
,React
基本已经废掉了过去很多基于组件的逻辑抽象模式,抹掉了 JSX
对比模板的一个优势,Vue3
中现在也都能做到,所以我会偏向 Vue3
。
(如果公司主要用 React
技术栈的话):所以总的来说我觉得要是一些不大的系统或者 H5
就用 Vue
,因为不管是上手还是开发难度上都很简单,开发效率也高嘛,而且它有更小的打包体积,毕竟在移动端网络差异大的情况下,资源体积是非常重要的。但像是一些中后台系统,或者一些大点的项目,会越做越大的,多人协作开发的,就用 React
,因为它的函数式编程有更加灵活的结构和可扩展性,丰富的生态圈和工具链,解决方案多,后期也更方便迭代与维护,还适用原生 APP
,所以我会偏向 React
。
你觉得这两框架哪个厉害
这个,我觉得吧,我们讨论这个问题的时候,可能由于咱俩关于这一块儿的信息不对等,只是表达自己想法的话,有可能会变成两个阵营的,而且即使证明了一个比另一个牛比,也不意味着我的项目就牛比了,反正好用就都学,让自己变得厉害才更靠谱一点
结语
如果本文对你有一点点帮助,点个赞支持一下吧,你的每一个【赞
】都是我创作的最大动力 ^\_^
更多前端文章,或者加入前端交流群,欢迎关注公众号【沐华说技术
】,大家一起共同交流和进步呀
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。