前端框架经历了十多年的争奇斗艳百花齐放,经历了 JSP、jQuery、Ember、Angular、React、Vue、Solid、Svelte 等等。如今所有人都要承认的一个事实是:在上百个前端框架中,最具影响力的只剩下了两个,Vue 与 React。
Vue 进入 3.x 时代已经将近 2 年了,React 也在今年 3 月 29 日发布了 React 18 版本。
今天就来聊聊在当今 2022 年,两者还有哪些区别。
下面我们从头开始对比它们,看看到底谁更胜一筹。
安装与启动
从两个框架的安装开始。
Vue
Vue 提供了 Vue CLI 创建 Vue 项目,安装命令如下:
安装成功后可以通过查看版本来确定安装成功。
创建新的项目运行以下命令:
React
创建 React 项目的工具是 create-react-app,简称 CRA。
创建新的项目运行以下命令:
结论
两者在安装和启动项目上几乎一致,平手。
Props
两个框架都是使用组件作为基础开发的,那么父子组件传值就成了一个问题。props 是将数据从父组件传递给子组件的关键技术。
Vue
在 Vue 中,props 使用普通的字符串传递。也可以通过 v-bind 指令传递变量,缩写是冒号(:)。
父组件传值:
子组件访问 props 需要使用 defineProps 函数:
React
在 React 中,props 是通过花括号传递变量的。
父组件传值:
子组件通过参数的方式获取 props:
结论
在传递 props 时,Vue 需要在属性前面额外添加指令,如果忘记添加指令会导致传递字符串。React 则不会有这种情况。
在子组件取值时,Vue 需要调用 defineProps 函数,React 通过函数的参数获取,更加自然。
综合对比,Vue 心智负担更大,React 则更加自然。这一轮 React 胜。
Event
Vue 使用了模板语法,React 使用了 JSX 语法。所以在编写 HTML 上发生了变化。但我们仍然需要为元素添加鼠标事件、键盘事件等。事件的处理也是一个必须事情。
Vue
Vue 处理事件通过 v-on 指令完成的,简写是 AT 符号(@)。
React
React 创建事件的方式和原生 HTML 几乎一致,区别是将绑定事件的属性名要求为驼峰命名法。
结论
React 更加自然,Vue 仍然是需要额外的操作符,如果忘记添加操作符,就会变成传递字符串的 props,React 则没有这个问题。这一轮 React 胜。
State
两者都是数据驱动的响应式框架,那么管理状态就成了一个关键问题。
Vue
在 Vue 中,通过 ref 或者 reactive 来创建状态。
两者的用法稍有不同,ref 是用来处理基础类型的状态的,而 reactive 通常处理引用类型的状态。
使用 ref 状态时需要通过 ref.value 来访问状态。
监听某个状态变化的方法是 watch 和 watchEffect。
两者的区别是 watchEffect 会在最初运行一次。
React
React 使用 useState 来创建状态。
React 使用 useEffect Hook 来监听状态变化。这个 Hook 接受一个回调函数和一个依赖数组。当依赖数组中任意一个状态发生变化时,回调函数就会触发。
结论
Vue 在创建状态和监听状态时分别提供了多种方式,我们在使用时需要考虑哪种情况该用哪种 API,而 React 分别只提供了一种方式,但是它同样可以做到应对各种情况。综合对比,Vue 心智负担更高,React 更简单。这一轮 React 胜。
Ref
尽管两门框架都使用组件进行编程,但我们还是难免需要访问 DOM,比如添加动画、控制输入框焦点等。为了解决这类问题,两门框架都提供了 ref 的概念,使用它可以创建对 DOM 的引用。
Vue
Vue 提供了 ref API。
React
React 提供了 useRef Hook。但是要访问 DOM,需要使用 ref.current 属性。
结论
几乎没什么区别,平。
双向数据绑定
我们在使用 input、select、textarea 这类元素的时候,输入的值需要和状态进行同步。而状态发生变化时,元素的值也应该被同步。这个功能被称作数据双向绑定。
Vue
Vue 提供了 v-model 指令创建双向绑定。
React
React 没有为这项功能单独提供 API,但我们也可以实现。
结论
从语法上看,Vue 更简洁。但是这会破坏单向数据流的原则,因为改变数据的方式不再是只有一种。React 的代码虽然不简洁,但更加容易追踪状态。这也是 React 和 Vue 在设计理念上的不同。在「让开发者写更少的代码」和「代码结构更加清晰易于维护」之间,Vue 选择了前者,React 选择了后者。至于谁好谁坏,个人更加倾向于后者,但是也有人倾向于前者。因为是取舍问题,平。
动态渲染
有些时候我们的组件是根据某些条件进行渲染的,这也就是动态渲染。
Vue
Vue 提供了三个指令:v-if、v-else 和 v-show。
React
React 没有为这种功能提供任何 API,而是使用原生 JavaScript 的条件语句,if、&& 或者是三元运算符等。
结论
Vue 的语法是在元素上添加特殊的属性,而 React 的语法是纯粹的 JavaScript 语法。从语法上看,没有太大差别。但是 Vue 会有额外的学习成本。综合来看,这轮 React 略胜一筹。
渲染子组件
有时我们需要在组件中将子组件传递给其他组件一起渲染。
Vue
Vue 提供了 slot 来传递子组件。
容器组件:
父组件:
React
React 的子组件是一个 props 上面的一个属性:children。
容器组件:
父组件:
结论
从上面的例子中看不出两者太大的差距。但是在更复杂的情况下,比如要传递 N 个子组件。React 可以通过属性进行传递,操作组件就和操作变量一样;Vue 则有了命名插槽、插槽动态名称、范围插槽等概念,操作起来比较麻烦,而且心智负担也高。这一轮 React 胜。
总结
通过本文,我对比了两个框架中大部分的概念和语法,各自有各自的优势,很难说清楚到底谁更好。
早在 2016 年左右我第一次对两者做对比的时候,感觉差距还是蛮大的,那时候 React 还是 class 组件的时代,还要靠 this.setState 来更新状态,组件也拥有很多复杂的生命周期。Vue 还是 Options API 的时代,也不怎么好用,比如 this 的问题;data 必须传递函数再返回一个对象;所有东西都要定义,使用组件要定义,使用事件要定义......
再来看今天的 React 和 Vue,似乎都在向同一个方向房展,而且越来越像。
虽然有相互借鉴的成分存在,但是从几年前就一直有一个质疑的声音,说 Vue 抄袭 React。特别是 Vue3 推出了 Composition API 之后,越来越像 React。甚至于有人说 Vue3 的代号海贼王,就是暗喻自己是从 React 那里偷走了很多东西。
你认为呢?