瑜亮之争:Vue与React的差异

在 React 和 Vue 之间存在许多相似性。Vue 的设计理念充分汲取了 Angular 和 React 的优点并将它们结合起来,所以如果你真的特别喜欢 React 所拥有的每个特性,那么在Vue 中同样可以发现它们。但是,React 和 Vue 之间除了拥有很多相似性,还有很多差异性。这里所指的差异性不包含所有细微的差异 —— 语法差异、方法名称差异 —— 仅包含那些在框架基本层面中所体现的差异性。

变更

这两个库中最本质的区别在于,当使用 React 时,直接变更 state 是非常不被鼓励的行为,而在 Vue 中,替换或者修改 data 则是更新它的唯一方式。还可以通过将 Redux 和 vuex进行比较来看出这一点 —— 在 Redux 中,当你想要修改一个已有的 store 时,会生成一个新的 store,而在 Vuex 中则会直接修改已经存在的 store。

在 React 中,要更新一个组件的 state,可以使用 setState :

之后,新的 state 将会与当前的 state 对象进行合并(使用浅合并策略)。

而在 Vue 中,则需要直接修改 data :

this.user.name = newName;

JSX 语法与模板语法

React 和 Vue 之间的另一个本质区别在于页面中数据的渲染方式。在 React 中会使用JSX,它是由 Facebook 发明、可直接在 Javascript 文件中编写 HTML 的语法。在 Vue中,如果你愿意,也可以使用 JSX 语法,但大多人还是使用模板语法,它具有类似Angular的模板语法、指令和数据绑定语法。

在 React 中,由一个数组生成 HTML 列表的 JSX 代码大概看起来会是这样的 :

在 Vue 中,实现同样功能的模板代码如下所示 :

CSS Modules

React 和 Vue 中最后一个主要差异点是在 Vue 中编写 CSS 的方式。React 中没有提供相应的内建功能,所以通常会使用 CSS modules。

在 React 中,会像这样使用 CSS modules :

Vue 也支持 CSS modules,而且无须配置任何额外插件和构建工具。大概看起来会是这样的(如果使用单文件组件):

但是在大多数情况下,你会注意到人们往往在 Vue 中使用 scoped CSS。在 Vue 中,scoped CSS 的工作原理是为当前组件产生的每个元素生成一个随机的 data-* 属性,然后将其添加至每个元素相应 CSS 选择器的末尾。在 <style> 标签中编写的任何 CSS 代码仅会应用于由该组件生成的元素。

使用 scoped CSS 的方式重新编写上一个例子会像这样 :

尽管在 style 标签中的 CSS 代码使用了通用的类名称,而且看起来它们可能会应用于组件外的其他元素,但它们确实将仅适用于该组件元素当中的子元素。话虽如此,仍然推荐使用更长、更具有表述性的类名。

scoped CSS 同时也可以和 SCSS 或者其他的 CSS 预处理器搭配和嵌套使用。

生态

由于 React 受欢迎和被广泛使用的程度,它拥有庞大的生态系统。Vue 作为一个较新的、还不太流行的库,目前还没有诸如 React 那样的生态系统和社区 —— 不过它每天都在变得更好,并且当前它的增长速度比 React 的生态系统还要快。

不幸的是,在 React 的生态系统中,尤其是那些至关重要的任务(比如路由)通常可能会非常零散。React 中存在多种路由解决方案 —— 尽管 react-router 似乎是最常用的。而在 Vue 中只有一种 vue-router。虽然 Facebook 已经交由社区去开发那些不属于 React本身的库,但 Vue、vue-router、vuex、vue-test-utils、vue-cli 以及未来更多的官方库的开发和维护团队却是相同的。

在实际应用中,如果使用的是官方 Vue 插件提供的功能(路由、状态管理、测试),那么你将会拥有不错的开发体验并且无须做出任何选择。但是如果使用的不是 Vue 的官方插件(如国际化插件、HTTP 资源管理插件等),那么你获得的开发体验将远远不如生态更加成熟的 React。

现在,来看一看那些能够帮助我们的官方插件。

路由

在 React 中,我们有多种客户端路由解决方案,但到目前为止,使用最广泛的方案仍是react-router。这个库使用 JSX 语法来描述当页面路径与给定路由规则匹配时所需要显示的组件。

vue-router 是 Vue 中处理客户端路由的官方库。它使用对象来配置路由而不是 JSX 语法。

两个库以不同的方式来完成相同的事情。

状态管理

React 中最常用的状态管理库是 Redux,它在 Vue 中等效的官方插件叫作 vuex。它们都使用基本相同的方法,提供一个全局的、可在整个应用程序中存储和修改数据的 store。如果熟悉 Redux,也可以轻松上手 vuex,反之亦然。它们之间的不同点在于术语和修改的差异性。

使用 Redux 你会拥有一个存储状态(state)的 store。你可以直接访问 state,也可以使用react-redux 并在中间件中使用 mapStateToProps 函数使其能够作为 prop 被访问。要更新 state,需要使用 reducer 来生成一个新的 state。Reducer 是同步的,要实现异步的话,可以在组件中进行修改,也可以通过插件(如 redux-thunk)来将异步 action 增加到应用程序中。

使用 vuex,同样拥有一个存储状态的 store。可以直接访问 state,但是却无法直接修改它 :要更新 state,必须通过 mutation,它是 store 中用于更改数据的特殊方法。Mutation只能是同步的,所以如果要异步修改某些内容(比如直接在 store 中将一些内容更新为从某个 API 返回的数据),可以使用 action。可以在不使用任何其他插件的情况下完成这些工作 —— 仅包括 Vue 和 vuex。

在 React 和 Vue 的组件中,使用 store 的方式完全不同。在 React 中, 你 必 须 将 整 个 组 件 封 装 在 一 个 Redux 中 间 件 中, 该 中 间 件 使 用mapStateToProps 和mapDispatchToProps 参数将 action 和 state 以 props 的形式传给组件。

由于 Vue 和 vuex 属于同一个能够协同工作的生态环境,使用起来更加容易。不需要为组件添加任何额外代码,即可以通过 this.$store 来访问 data。当组件被挂载时它会获取 users,然后当 users 加载完成时,users 即可通过 this.users来访问。vuex 也提供一些帮助函数来减少代码的冗余性。

组件单元测试

对 React 组件进行单元测试的常用解决方案是使用 Enzyme。Enzyme 是一个由 Airbnb 开发的库,使用它可使加载和测试组件变得更加容易。Vue 拥有一个非常类似的库 vue-test-utils。与 Enzyme 一样,它也提供加载组件、遍历DOM 等功能,从而使测试组件变得更加容易。正如你所见,它们拥有相似的语法,所以在它们两者之间进行切换将是一件十分容易的事。

本文节选自《Vue.js快跑:构建触手可及的高性能Web应用》一书附录中对Vue与React异同的分析和对比,对于尚未入坑的前端工程师有一些借鉴作用。一些更细节的实现方法和注意事项,书中都有详细的实战案例和思路讲解,阅读原文即可触手可及,拥抱高性能Web应用。

内容简介:本书是用Vue.js构建Web应用的全方位指南。作者运用细致入微的讲解方式带你领略Vue.js的独特魅力,致力于协助你从零开始基于Vue.js创建一个Web应用。本书共7章:第1章介绍Vue的安装及基本用法,覆盖大量Vue核心技术,诸如响应式原理、生命周期钩子等;第2章到第6章进入Vue高阶世界,通过在丰富的组件特性中遨游,教你使用vue-router和vuex来实现客户端路由和状态管理,以此完善整个Web应用的功能;最后一章介绍如何使用vue-test-utils这一官方测试利器来为组件编写单元测试,从而保证Web应用的正常运行;附录分别介绍vue-cli用法及Vue 与React之间的异同。本书适合对HTML和JavaScript已有一定了解,正在准备或已经使用Vue.js进行Web应用开发的从业者,也适合希望通过学习框架使用来提升对其认识的开发人员,有React使用经验的读者同样可从中获得启发。

原文发布于微信公众号 - 前沿技墅(Edge-Book)

原文发表时间:2018-12-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券