历史的车轮滚滚而来,我们正处于前端框架盛行的时代,而 Vue 和 React 每年都会在“最喜爱、最常用或最受欢迎”的排名中登顶 🔥。它们都为开发人员提供了一种构建各种 Web 应用程序的高效方法 ✨。
本文,我们将从以下几点来进行探索:
- 为什么需要 Vue 或者 React 等 JavaScript 框架 ?
- 为什么对比 Vue 与 React ?
- Vue 概览
- React 概览
- Vue 和 React 谁更受欢迎?
- Vue 和 React 的性能对比
- Vue 与 React 未来方向
为什么需要 Vue 或 React 等 JavaScript 框架?
接下来我们一起来回顾下从 2000 年初期到现在前端的发展历程。
请大家看下面的图片,要实现下图的效果是不是很简单?
开始阶段- HTML、CSS、JavaScript
让我们时光倒流到 2000 年 🔙。软件工程师编写网页的方式是使用纯 JavaScript(或更正式的 ECMAScript 版本 3),结合级联样式表(CSS 版本 2)和 Web API 来操作 DOM 的内容,如图所示下图中的模型(下图),其中有两个不同的层,顶部是开发人员编写的应用程序代码,底部是 Web API 和 DOM,它们只为应用程序代码提供低级别的抽象功能.。
下面的代码片段显示了 Web 应用程序的一种简单的实现,以纯 HTML 格式显示数据列表。其流程简单明了,从上到下依次是页面标题、搜索框、搜索按钮、数据列表、js 脚本。
<html>
<body>
<h3>List</h3>
<input id="search-input" class="search-input" />
<button id="search-button" class="search-button">
搜索
</button>
<table id="table-data" class="table-data">
<thead>
<tr>
<th colspan="2">Table Header</th>
</tr>
</thead>
<tbody id="data-list" class="data-list"></tbody>
</table>
<script src="main.js"></script>
</body>
</html>
在 main.js 中用 ajax 获取数据渲染列表, bootstrap 调用 fetchJson 获取数据,然后用函数 appendListToDataList 填充 table 列表。
document.body.onload = bootstrap;
function bootstrap() {
var dataList = document.getElementById(’data-list’);
fetchJson(DATA_URLS.list(), appendBreedToDropDown(dataList));
}
function appendListToDataList(dataList) {
return function (data) {
data.forEach(function(item) {
var tr = document.createElement('tr');
Object.keys(item).forEach(function(name) {
var td = document.createElement('td');
td.textContent = name;
tr.appendChild(td);
});
dataList.appendChild(tr);
});
}
}
function fetchJson(url, callback) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
var myArr = JSON.parse(this.responseText);
callback(myArr);
}
};
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
我们可以很容易地发现使用原生 JavaScript 有几个缺点:开发人员需要担心同一脚本中的多个问题,包括修改 DOM 以添加动态行为、获取远程 API 和处理副作用(副作用是在函数内部修改外部的状态变量),并维护应用程序状态。从长远来看,关注点分离是实现可维护性和可扩展性的关键。
当时的另一个问题是完成简单任务的许多步骤很冗长,例如使用函数 fetchJson,它发出 GET 请求获取到数据就占用了 7 行代码。
JQuery 时代
开发人员很快意识到需要在低级 API 和应用程序代码之间添加一个抽象层,以减少执行 DOM 操作所需的步骤数。以这种方式提高可读性并解决当时的另一个常见问题,浏览器在其实现中不遵循 DOM 标准,导致浏览器中的相同代码在另一个浏览器中以不同的方式工作。因此,抽象层可以在内部处理这些差异,为开发人员提供更加透明和简化的 API,如下图所示:
用 JQuery 重新改造下上边比较复杂的代码:
function appendListToDataList(dataList) {
return function (data) {
data.forEach(function(item) {
$dataList.append(
$("<tr></tr>")
.append(function() {
Object.keys(item).forEach(function(name) {
$("<td></td>")
.text(name)
});
})
);
});
}
}
function fetchJson(url, callback) {
$.ajax({ url, success: callback });
}
前端开发中 JQuery 在可读性、可维护性和浏览器兼容性方面领先一步。但是,在大型 Web 应用中实现规模化仍然存在一些问题;其中一个问题是使用基于选择器的查询来处理 DOM 的必要性。每当开发人员需要添加更多的 HTML 元素或修改现有的元素时,她或他也需要对相应脚本进行更改。以这种方式工作很容易错过正确的选择器和 HTML 结构,更不用说开发人员如何对这个 Web 应用程序进行功能测试了。
React、Vue 等 JavaScript 框架时代
与桌面或服务器应用程序等其他领域的开发类似,前端工程师们意识到他们需要构建复用型库或完整框架的应用程序,这些应用程序根据设计理念(架构风格)提供功能,以解决项目中出现的各种问题(比如我们上述两个时代时遇到的),具体取决于功能和非功能要求。
现在 Web 应用程序开发的工作方式与上图非常相似,其中前端工程师以现有的一组框架库为基础,这些框架库提供了更高和更丰富的功能,而这些框架或者库将整个操作 DOM 的逻辑封装成了更为高效的 VDOM 也就是大家熟知的虚拟 DOM,整体的架构思想也变为了以数据驱动视图,视图再反作用于数据的 MVVM 的设计思想。
还有,前端工程化的蓬勃发展,让整个前端也变得更加规范,效率也更加高效,不少大厂也在提出各种大前端的模式,不过这里我们就不过赘述了,回归主题 💁。
到了这里,我们简单的回顾了前端从 2000 年初到现在的一个历程,可以发现一个很有意思的历史变迁的现象:人类的发展进化史,最开始用拳头之后会借助自然制造一些简单便捷的工具随着发展又创造一些更为复杂的工具。大家可以发现一个共同的特性,就是提高效率。
相信现在我们更加明确了 Vue 和 React 对于现在前端的重要性了。
为什么对比 Vue 与 React?
为什么要比较 Vue.js 和 React?主要原因是时间。这两个框架都可以实现相似的结果,在社区中很受欢迎,并且被成功的商用。但是它们之间又会有一些差异,比如学习曲线、实现方式、适合场景等。
所以,如果你是一名开发人员,你会知道掌握技术需要付出很多努力。通过选择一些技术来深入学习与研究,你不会成为一个天马行空的万事通。
同样,如果你是技术领导者或企业主,你希望为你的项目选择最合适的技术,以最大限度地降低风险。
简单比较 Vue 和 React
Vue 对新手更友好,而 React 需要扎实的 JavaScript 基础。两者都支持 JSX,但 Vue 默认使用 HTML 模板(稍后会详细介绍)。
Vue 概览
介绍
Vue 是框架中的新星 ☘️。它是由前 Google 工程师尤雨溪创建的。他的目标是结合 Angular、Ember、React 的优势,同时平衡它们各自的弱点。 Vue 于 2014 年首次发布,然后在 2016 年重新启动。该框架现在由 Vue.js 核心团队开发和维护,当然,还有社区贡献者。
时至今日,在各大小公司中都可以看到 Vue 的身影。
设计理念
关键词:响应式、VDOM、template、跨平台、双向数据流。
知道了 Vue 的设计理念,我们用实际的 demo 来看看这些关键词概念是如何体现的:
沿用上述为什么需要 Vue 或 React 的例子
这里我没有抽象出组件,但不代表 Vue 不具备这个能力,我这里只是重点表示这里我没有抽象出组件,但不代表 Vue 不具备这个能力,我这里只是重点表示 Vue 的数据流、template
在该例子里可以很明显看出 Vue 的模板对于新手开发的友好度还是很高的,用过之前 JQuery template 的同学应该很熟悉这种模式;值得一提的还有它的双向数据流,在实际开发时可以少写一写逻辑,也是很方便的。
React 概览
介绍
React 是由 Facebook 的开发者 Jordan Walke 创建的。该库于 2011 年首次在 Facebook 新闻提要中使用,一年后在 Instagram 上使用,并于 2013 年向所有人开放代码。 React 是当今 JavaScript 框架的领导者 👨💼。该框架目前主要由 Facebook 团队负责维护和新方向的探索。
设计理念
我找到 2013 年 React 团队发的一篇博客,为什么我们要构建 React ?可以看到起初 React 的设计初衷用以下关键词来表示:JSX、响应式、VDOM、跨平台、单向数据流。
知道了 React 的设计初衷,我们可以大概了解 React 的工作方向,接下来用一个简单的 demo 来看看,React 在实际开发中是如何完成他的设计理念的:
沿用上述为什么需要 Vue 或 React 中的例子
第一步:设计组件
从上图中我们可以清晰的看到:
- FilterableProductTable (黄色): 是整个示例应用的整体
- **SearchBar (绿色色):**搜索栏目
- **ProductTable (蓝色):**展示_数据内容_并根据_用户输入_筛选结果
- **ProductCategoryRow (红色):**表头
- **ProductRow (黑色):**每一行展示不同的样式/数据
现在可以根据组件的层级来表示:
- FilterableProductTable
- SearchBar
- ProductTable
- ProductHeader
- ProductRow
设计好组件后,我们也完成了 React 设计理念中的 JSX 部分和 VDOM 部分(VDOM 是基于 DOM 的一种抽象的表示方式,这部分在 React 内部实现,如果只是编写组件你不必关心)。
第二步:构建组件的静态版本
按照 React 的设计,我们不仅要关注组件的拆分,还要注意数据/状态的分离,并且 React 推崇自上而下的构建应用,这也就意味着首先从层级最高的组件 FilterableProductTable 开始或者是从最基本的组件 ProductRow 开始。
点击查看【codepen】
第三步:确定交互用到的 state
保证 state 最小,且完整
我们的例子中有以下数据:
- 人物初始数据列表
- 搜索框数据
- 经过搜索筛选的人物数据列表
通过问自己以下三个问题,你可以逐个检查相应数据是否属于 state:
- 该数据是否是由父组件通过 props 传递而来的?如果是,那它应该不是 state。
- 该数据是否随时间的推移而保持不变?如果是,那它应该也不是 state。
- 你能否根据其他 state 或 props 计算出该数据的值?如果是,那它也不是 state。
「人物初始数据列表」,不是 state,因为它是由 props 传递而来的;「搜索框数据」是 state,因为它随时间的推移而变化而且无法通过计算得来;「经过搜索筛选的人物数据列表」不是 state,因为它可以通过人物初始数据列表和搜索框数据计算得来的。
所以,我们现在知道「搜索框数据」是 state 。
第四步:确定 state 的位置
点击查看【codepen】
我们已经确定了最小 state,接下来我们要明确该 state 会影响哪些组件,并最终确定 state 应该在哪里被声明。
对于应用中的每一个 state:
- 找到根据这个 state 进行渲染的所有组件。
- 找到他们的共同所有者(common owner)组件(在组件层级上高于所有需要该 state 的组件)。
- 该共同所有者组件或者比它层级更高的组件应该拥有该 state。
- 如果你找不到一个合适的位置来存放该 state,就可以直接创建一个新的组件来存放该 state,并将这一新组件置于高于共同所有者组件层级的位置。
根据以上策略,代入我们的例子:
- PersonTable 需要根据 state 来进行筛选;SearchBar 需要展示 state 。
- 它们的共同所有者为 FilterablePersonTable 。
所以,state 很自然的放到了 FilterablePersonTable 中。
第五步:添加反向数据流
点击查看【codepen】
React 通过一种比传统的双向绑定略微繁琐的方法来实现反向数据传递。尽管如此,但这种需要显式声明的方法更有助于人们理解程序的运作方式。
如果你想查看更多关于 React 设计相关的内容,>>戳我跳转<<
Vue 和 React 谁更受欢迎?
使用度对比
从使用度可以看出 React 保持领先,但是从 2019 年开始到 2021 年并没有增长的迹象,而 Vue 一直保持增长状态。
满意度对比
这张图中 React 和 Vue 很接近,我们下面单独列出来比对;不过有意思的是,随着新技术 Solid 和 Svelte 的出现,在满意度上是超过了 React 和 Vue ,有兴趣的同学可以自行去了解。
Vue 和 React 单独比拼 🤺
有趣的是,Jet Brains Dev Ecosystem 2021 调查显示的数字略有不同,并显示这两个框架的开发人员专业知识和常规使用率都很高,Vue.js 正在上升。 Vue.js 用户的份额从 2020 年的 34% 增长到 2021 年的 43%,而 React 的同比增长则从 64% 下降到 49%。
下面再来看一组 stack overflow 的数据对比:
每月的问题数量:
受欢迎与喜爱度对比:
可以看出来,在 stack overflow 中 React 的问题数量是遥遥领先的而且增长态势明显,Vue 相对就比较少了,所以大家以后针对这两个框架遇到的问题,知道去哪里提问或者找答案了吗?
小结
可以看到,整体上 React 更受欢迎,但是 Vue 的增长速度很快,React 基本已经趋于稳定了,相信按照这样的增长情况来看,Vue 超越 React 是迟早的事情。
Vue 和 React 的性能对比
在 vue-v3.2.37 与 react-v17.0.2 的对比中,Vue 在所有测试中的表现都更好。 这绝不是对 Vue 与 React 性能的详尽测试。但是,它可以作为一个强有力的指标。
看到这里,React 的用户可能会不满 🙃
Vue 和 React 的未来方向
Vue 的未来方向
全新的文档
当然,全新的文档已经发布了,整体还是熟悉的 Vue 风格,但是它的教程更加丰富了,增加了用户友好度与易用性,也可以看出来 Vue 对于用户交互体验的提升,从这里可以看到 Vue 未来一定不会有大刀阔斧的更新了(当然,仅我个人观点 :P )。
TypeScript 持续完善
可以看出,尤雨溪对于 TypeScript 还是很看重而且很支持的,当然,我个人也认为 TypeScript 在未来一定是大趋势,所以,大家可以慢慢学起来了。
模板语法-作用域插槽
编译时优化是趋势
同时处理前端和后端的垂直解决方案
React 的未来方向
全新的文档
当然,全新的文档还在 beta 版,点这里可以查看。新文档主要是依照 Hook 方式来的。我的看法是就很棒 🙃 。
优化编译器
按照 React 官方的文档介绍是他们已经完成了对于编译器的优化,并且还有配套的 playground 。
服务端组件
这个是我比较关注的,大体的动机:
拥抱 Hook
从 React 发布 Hook 到 Vue 发布组合式 API 以来,大家都朝着 Hook 的方向在发展,虽然现在市场的主流还是 React Class 模式,Vue Options 模式,但是之前的那种方式开发会让一个组件渐渐变得庞大且难以维护(俗称“屎山”);所以,有条件的同学可以开始全面拥抱 Hook 了。
总结
我尝试这样做个比喻(可能不太恰当,勿喷):React 像一个年长的正规军,它总是很沉稳并且很规范而 Vue 则像一个怀揣着理想的年轻人,刚开始学着前辈的样子去驰骋疆场,到后来历经磨难,慢慢开始走向正规化,规范化。
写这篇文章不是想拉拢大家去用 Vue 或者 React 的某一个,只是想让大家对于这两个相爱相杀的“朋友”有更多的认识,我相信,在你看完这篇文章后对于选择用哪个框架心里一定有自己的选择。
再次声明:Vue 和 React 都是市面上优秀的框架,它们可能只是最佳适用场景可能会有一些不同。