【技术选型】react vs vue,从团队适用性、业务适用性、技术生态3大方面综合考虑

我正在参加「掘金·启航计划」

前言:react和vue选哪个

前端框架经过十多年的争奇斗艳百花齐放,经历了JSPjQueryEmberAngularReactVue等,如今逐渐进入稳定发展阶段,剩下了2个最具影响力的框架:ReactVue
新建项目时,面对ReactVue主流框架,相信很多小伙伴会遇到如下疑问,框架选择犹豫不决:

  1. 公司团队经常用什么我就用什么吗?
  2. 这2个框架各有什么优点和缺点?
  3. 近几年Vue3、React18 相继更新升级,我要在团队里做第一个吃螃蟹的人的吗?

以上问题咱们暂且放一放,先来从”团队适用性、业务适用性、技术生态“3个方面全方位细致地了解React和Vue框架,最后该选哪个框架自有答案~~❤️

选型对象

React18.x 和 Vue3.x 版本

对比考虑的因素

1. 团队适用性

  • 以开发者角度来看:

    如果你是才入职到新环境的开发,并且接手的是一个成熟的项目,处于正常迭代阶段,那不要想着颠覆团队已有技术栈,技术栈切换相当于重构,需要很多人力和时间成本。

  • 以项目负责人角度来看:

    如果你是项目负责人,在新建项目时候需要做技术选型,那么在对比技术生态的同时,还需要考虑团队开发成员对技术栈的熟悉程度,选择大多数人都熟悉的技术栈,有助于提升项目产出效率和质量;但如果大多数人都选择尝试新技术,并且有信心面对各种挑战,也可以考虑新的技术栈。

  • 结合历史项目来看:

    在做技术选型的时候,还应着重调研参考公司历史项目使用的技术栈。如果历史项目做技术栈切换重构,需要有相应的开发、测试、产品、运维等人力投入,因此会带来巨大的不可控风险,如果恰逢业务方等着要业务需求交付的话,上下游工作都会被影响。所以历史项目重构需谨慎考虑!!!

2. 业务适用性

  • React 适用于构建大型、复杂的单页应用,比如to B 管理系统等
  • Vue2.x options API 适用于中小型的单页应用,但Vue3.x composition API 和 Typescript 的加持也可以开发大型项目,比如to C 移动端应用等

以上结论,是通过对比React、Vue的技术框架特点、优缺点总结的,下面我们从技术生态角度来具体对比2种框架看看~

3. 技术生态

概述简介

react

React,起源Facebook内部项目,整体采用函数式编程,使用 JSX(JavaScript 语法扩展)开发灵活度较高,可用于构建用户界面应用(Web应用程序和原生应用)的JavaScript框架。

特性:

  1. 函数式编程:使用纯函数稳定无副作用(输入相同,输出结果一定相同),使代码可复用性和可维护性提升。React16后出现的hooks,更进一步提升可复用性。
  2. 响应式(单向数据流):数据流自顶向下,从父节点传递到子节点,如果顶层(父级)某个props改变了,React会重新渲染所有子节点。
  3. 高效(Virtual DOM):Virtual DOM,最大限度地减少DOM操作。
  4. JSX 灵活:使用JSX语法构建组件化代码,React组件有2种:函数组件(无状态组件,可继承)、class组件(有状态组件)。
  5. TS支持完善:Tsx 的开发体验完全来自于 TS 专门针对 Jsx 制定的一整套推导机制。

vue

Vue,是渐进式JavaScript框架,它基于HTML、CSS和JavaScript构建,并提供了一套声明式、组件化的编程模型,用于开发用户界面应用。

特性:

  1. 易上手:基于标准HTML、CSS和JavaScript三件套风格,简单易上手。
  2. 渐进式:无论学习还是实际开发,周边生态都是可选的不是必需的,当需要用到路由,引入vue-router;系统业务复杂需要用到状态管理,引入vuex/pinia。
  3. 响应式(双向绑定):vue2底层使用Object.defineProperty对数据监听实现响应式处理,vue3则使用Proxy做代理。
  4. 声明式(vue3):vue3升级更新,出现composition API,使用声明式函数编程,提升了可维护性。高可复用的逻辑功能则抽离为hooks,和React hooks有异曲同工之妙。
  5. TS支持良好:官方的建议,用<script setup lang="ts">+vscode+volar,一样能获得非常好的 TS 体验。
  6. 性能优异(中小型项目):具体比对参数详见“性能对比”部分。

设计原理

react

React 框架设计为单向数据流传递,数据通过 state 状态管理。当调用 setState 修改数据会更新渲染整个 vdom,期间需要大量计算。所以为了确保渲染性能,框架内部使用 reconcile 调和器将 vdom 转换为 fiber(双链表),且设置允许打断渲染机制,由 schedule 任务调度器实现。完整的渲染过程如下图所示:

【技术选型】react vs vue,从团队适用性、业务适用性、技术生态3大方面综合考虑

vue

VueReact 框架设计原理比较雷同的就是,引入Virtual DOM,本质也是为了减少DOM操作,实现数据响应式,其他就不太相同了。Vue基于HTML、CSS和JavaScript模板开发的,因此整个渲染过程,需要渲染器、编译器和观察者,如下图所示:

【技术选型】react vs vue,从团队适用性、业务适用性、技术生态3大方面综合考虑

性能对比

对比说明

  • 本章节性能对比的数据皆有据可查,对比仅覆盖了些常见应用场景,但未能覆盖全局场景。
  • 对比数据(可点击查看),可根据条件筛选框架对比的结果
  • 测试对比的对象:Vue v3.2.47React v18.2.0
  • 测试使用浏览器及设备系统:Chrome 113 – OSX

对比内容

  1. 这里主要是数据量较大的列表操作,对比维度如下:
  • 创建列表
  • 替换所有行
  • 局部更新
  • 选择行
  • 交换行
  • 删除行
  • 创建多行
  • 追加多行
  • 删除多行

结果可查看下图,绿色表示操作所需时间更短,黄色表示操作时间所需较长,红色表示操作所需时间很长。

【技术选型】react vs vue,从团队适用性、业务适用性、技术生态3大方面综合考虑

上图结论:可以看到Vue在数据量大的列表操作场景中近乎完胜,尤其是交换行的情况,Vue更是大幅领先。

  1. 启动指标,主要从以下几个方面对比:
  • 加载时长:主要指标是TTI(Time to Interactive),指从页面开始加载到页面可进行交互的时长,TTI值越小,代表用户可以更早地操作页面,体验就越好
  • 主线程工作时间:包含样式、布局、执行逻辑等
  • 网络传输字节数:值加载页面中所有资源的成本

【技术选型】react vs vue,从团队适用性、业务适用性、技术生态3大方面综合考虑

上图结论:还是Vue相对优秀

  1. 内存分配(以MB为单位),对比维度如下:
  • 页面加载的内存使用情况
  • 运行内存,添加 1000 行后的内存使用情况
  • 每 10 行点击更新 5 次后的内存使用情况
  • 创建/清除 1000 行 5 次后的内存使用情况
  • 创建 10000 行后的内存使用情况

【技术选型】react vs vue,从团队适用性、业务适用性、技术生态3大方面综合考虑

上图结论:还是Vue胜出

思考

以上性能对比是以1000行数据为基准的,如果数据量更庞大呢,5w或10w行,甚至50w行,数据会有变化吗?结论会有变化吗?

就本人来看,虽然以上性能对比React落于下风,但从React Fiber架构来看,大数据量的虚拟DOM比对时,React是具有优势的,此架构可以通过 Schedule 调度器设置任务优先级,尽可能地减少主线程阻塞,对用户体验的感知是相对友好的。

使用层面

JSX vs Template

React 采用 JSX 更为灵活,将HTML、CSS全都融入JS,属于 all in js。React中,渲染逻辑和标签共存于同一个地方——组件。
【技术选型】react vs vue,从团队适用性、业务适用性、技术生态3大方面综合考虑

Vue 则使用 Template 模版语法,和传统HTML、CSS、JS分离开发比较类似,虽然灵活度不如JSX,模版语法语法穷举所有原生JS能力,但对于新手更为友好。在Vue3框架中,从模版层面做了静态优化,对静态模板做标记,从而提升节点diff效率,使得框架渲染性能提升。

生命周期

react
  • 初始化挂载时(4个):
    • constructor:初始化组件state、事件处理(比如绑定节流、防抖函数)
    • getDerivedStateFromProps:通过比较nextProps和prevState,更新state,同时也方便处理为null的情况
    • render:将jsx转化为React Element元素。
    • componentDidMount:组件挂载到真实DOM,这时可以获取真实DOM节点。
  • 更新时(5个):
    • getDerivedStateFromProps:更新时,将props映射到state,具体处理同初始化。
    • shouldComponentUpdate:传入新的props、新的state和新的context,返回值判断是否继续执行 render 函数。
    • render:同初始化。
    • getSnapshotBeforeUpdate:执行在commit阶段,commit分为 Before Mutation(DOM修改前),Mutation(DOM修改)、Layout(DOM修改后),该钩子函数发生在 Before Mutation 阶段,可用来处理组件更新前的逻辑。
    • componentDidUpdate:组件更新后DOM操作。
  • 卸载时(1个):
    • componentWillUnmount:组件卸载,解除事件监听。
      【技术选型】react vs vue,从团队适用性、业务适用性、技术生态3大方面综合考虑
vue
  • 初始化阶段(3个)
    • setup:合并beforeCreate、created生命周期钩子,用做初始化数据和事件。
    • onBeforeMount(载入前):编译模版准备渲染,这时可以用来初始化数据,比如发起ajax请求。
    • onMounted(载入后):上面编译准备好的html内容,完成render,渲染生成真实DOM,这时候数据、真实DOM、事件已挂载处理,可以获取真实DOM做交互逻辑。
  • 更新阶段(2个)
    • onBeforeUpdate(更新前):组件或实例的数据更改,会触发该生命周期钩子,发生在vdom更新渲染之前。
    • onUpdated(更新后):数据更新,已完成重新渲染。这时候可以获取更新后的DOM。
  • 卸载阶段(2个)
    • onBeforeUnmount(销毁前):组件销毁之前,可以用来清除事件绑定,比如清除定时器。
    • onUnmounted(销毁后):调用后,所有的事件监听被移除,子组件被卸载。

【技术选型】react vs vue,从团队适用性、业务适用性、技术生态3大方面综合考虑

组件通信

ReactVue 组件通信有些许相似,具体有3种通信方式雷同,如下所示:

React
  1. 父组件->子组件通信:props
  2. 子组件->父组件通信:回调函数
  3. 跨层级通信:provide/inject
Vue
  1. 父组件->子组件通信:props
  2. 子组件->父组件通信:$emit 事件
  3. 跨层级通信:context
    【技术选型】react vs vue,从团队适用性、业务适用性、技术生态3大方面综合考虑

样式处理

React
  • className(嵌入式)
  • inline style(内联)
  • CSS Modules(外链)
  • 引入第三方依赖处理
    • styled-components
    • classnames
  • 预处理器
Vue
  • class + style scoped(嵌入式)
  • inline style(内联)
  • CSS Module(外链)
  • 预处理器

React、Vue样式处理使用层面虽然有些差异,但本质都是CSS处理,3种样式表引入方式都支持:行内样式表(行内式/内联)、内部样式表(嵌入式)、外部样式表(链接式)。

事件处理(onClick vs @click)

React

React 元素的事件处理和 DOM 元素的很相似,但是有一点语法上的不同:

  • React 事件的命名采用小驼峰式(camelCase),而不是纯小写。
  • 使用 JSX 语法时你需要传入一个函数作为事件处理函数,而不是一个字符串。
function Form() {
  function handleSubmit(e) {
    e.preventDefault();    console.log('You clicked submit.');
  }

  return (
    <form onSubmit={handleSubmit}>
      <button type="submit">Submit</button>
    </form>
  );
}
Vue

基本事件

Vue 使用v-on指令(简写为@)监听DOM事件,并在事件触发时执行对应JavaScript。

// 1. v-on
v-on:click="handler"
// 2. @
@click="handler"

事件处理器(handler)有2种:

  1. 内联事件处理器
const count = ref(0)

<button @click="count++">Add 1</button>
<p>Count is: {{ count }}</p>
  1. 方法事件处理器
const name = ref('Vue.js')
function greet(event) {
  alert(`Hello ${name.value}!`)
  // `event` 是 DOM 原生事件
  if (event) {
    alert(event.target.tagName)
  }
}

<button @click="greet">Greet</button>

自定义事件

使用 v-on 指令监听自定义事件,父组件绑定事件名(建议kebab-case 命名),子组件通过 $emit 触发调用,如下示例:

父组件:

<MyComponent @my-event="handleThis" /> 
<!-- 内联声明 --> 
<MyComponent @my-event="handleThis(123)" />

子组件:

this.$emit('my-event’, 'haha')

周边配套

React

路由管理

  • React-router

状态管理

  • Redux:基础的状态管理库
  • React-Redux:Redux插件库,用来简化
  • Redux-thunk:处理异步的中间件
  • Redux-saga:内部基于generator,也是用来处理异步的中间件
  • Mobx:使用简单,修改数据本身即可实现视图的更新

UI框架

  • ant-design
  • arco-design
  • chakra-ui
  • MUI

Vue

路由管理

  • vue-router

状态管理

  • vuex
  • pinia

UI框架

  • element-plus
  • vant

跨端处理

React

App

在跨 App 界的一哥是 ReactNative,以下简称 RN,因为本人没有亲自体验过,所以不做过多阐述,但是鉴于 RN 是2015年4月问世,时间不短,并且也有足够的团队使用,目前看来在前端跨端的领域成熟度已经相当高了。

小程序

对React支持度最好的当然是 Taro 了,一直在持续迭代中,也有来自京东凹凸实验室的背书,拥有较为稳定的产品和活跃社区,开发者可以大胆尝试,Taro 3 可以支持转换到 H5、ReactNative 以及任意小程序平台

Vue

App

原生App开发,对Vue支持度相对友好的有 WeexVue NativeCapacitor等框架。

小程序

uni-app 对Vue前端开发人员比较友好,学习成本比较低,uni-app是基于vue.js的。其次,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝)、快应用等多个平台。

兼容性

  • PC端ReactVue 均不支持IE8以下,对于个别浏览器兼容模式使用IE内核也可能是不支持的,具体要看使用的内核版本。尤其Vue3直接放弃对IE的支持。
  • H5端React没什么兼容问题,但Vue3响应式底层使用Proxy来实现,Proxy在IOS端最低支持10版本,polyfill处理兼容问题不能完全兼顾,因为是基于Object.defineProperty。所以业务环境对IOS9有兼容需求的,就不要轻易尝试了。

【技术选型】react vs vue,从团队适用性、业务适用性、技术生态3大方面综合考虑

总结

到了文末,关于 ReactVue 的选型,我们来做个总结,具体如下:

  1. 在选型前,我们首要看团队适用性(综合考虑历史因素和团队现状),以及切换技术栈的开发成本和增加上下游合作的时间成本。
  2. 再者还要充分考虑框架的兼容性,如果不满足业务需求,再优秀的框架也要pass掉。
  3. 然后了解框架原理,全面地对比React、Vue框架的性能特性、使用难易、周边配套、跨端处理等方面。

最后,不论 React 还是 Vue,都是相当优秀的框架,框架底层同样实现了Virtual DOM减少DOM操作,有着不错的性能,同时还有着声明式编程的特性,方便地维护代码。再者各自都拥有着活跃的社区和周边,在跨端上也有着不错的支持。所以,选哪个框架生态,就根据各自公司业务背景和需求来做抉择吧!!

参考:
krausest.github.io/js-framewor… (性能对比)
caniuse.com (查看兼容性)

原文链接:https://juejin.cn/post/7247770501325389880 作者:小铭子

(0)
上一篇 2023年6月24日 上午10:21
下一篇 2023年6月24日 上午10:31

相关推荐

发表回复

登录后才能评论