文档章节

使用 React 和 Vue 创建相同的应用,他们有什么差异?

 阿K1225
发布于 11/20 23:10
字数 3271
阅读 12
收藏 5

在工作中应用 Vue 之后,我对它有了相当深刻的理解。 不过,俗话说「外国的月亮比较圆」,我好奇「外国的」 React 是怎么样的。

我阅读了 React 文档并观看了一些教程视频,虽然它们很棒,但我真正想知道的是 React 与 Vue 的不同之处。 这里的“不同”,并不是指它们是否具有虚拟 DOM 或者它们如何渲染页面。 我希望有人能向我解释代码并告诉我其中发生了什么! 我想找一篇能解释这些差异的文章,以便 Vue 或 React(或整个 Web 开发)的新手可以更好地理解两者之间的差异。

但我没有找到任何解决这个问题的方法。 所以我意识到我必须自己动手,来发现相似/不同之处。 在做的时候,我想我会记录整个过程,以便产出一篇关于此的文章。

我决定尝试构建一个相当标准的 To Do 应用,它允许用户添加和删除列表中的项目。 这两个应用都是使用默认的 CLI 构建的(React 的 create-react-app 和 Vue 的 vue-cli)。 BTW,CLI 代表命令行界面。

 

好吧,这个介绍已经超出了我的预期。 我们先快速看看两个应用的界面:

 

 

两个应用的 CSS 代码完全相同,不过它们所在的位置有差别。 考虑到这一点,我们接下来看看两个应用的文件结构:

 

你会发现它们的结构几乎完全相同。 唯一的区别是 React 应用有三个 CSS 文件,而 Vue 应用一个都没有。 这样做的原因是,在 create-react-app 中,React 组件会有一个附带文件来控制其样式,而 Vue CLI 采用全包方法,具体样式在实际组件文件中声明。

最终,他们都达到了同样的目的,对于不能在 React 或 Vue 中以不同的方式构建 CSS 的问题,目前还真没什么办法。这真的取决于个人偏好 - 你会听到开发者社区关于如何构建 CSS 的大量讨论。 现在,我们将遵循两个 CLI 中列出的结构。

但在我们进一步讨论之前,我们先快速看一下典型的 Vue 和 React 组件的是什么样的:

扯远了。现在让我们开始研究细节中的细节!

 

 

如何变异数据?

 

首先我们要搞清楚什么是“变异数据”? 听起来有点科技感是吧? 它基本上只是意味着改变我们存储的数据。 因此,如果我们想将一个人的名字取值从 John 改为 Mark,我们就是在“变异数据”。 这就是 React 和 Vue 之间的关键区别所在。 虽然 Vue 本质上创建了一个 data 对象,对象数据可以自由更新,而 React 创建了一个 state 对象,要实现更新必须多做一点工作。 现在 React 有充分的理由实现额外的 legwork,我们稍微深入一下。 但首先,让我们看看 Vue 中的 data 对象和 React 中的 state 对象:

Vue data 对象在左侧。 React state 对象在右侧。

你可以看到我们已经将相同的数据传递到两者中,只是标记不同。 因此,将初始数据传递到我们的组件非常非常相似。 但正如上文提到的,我们对这些数据的修改方式在两个框架之间有所不同。

假设我们有一个name 为 'Sunil'的数据元素 。

在 Vue 中,我们通过调用 this.name 来引用它。 我们也可以调用 this.name ='John' 来更新它。 这会把我的名字改成 John。 我不确定被称为John的感觉如何,但嘿嘿,它就是发生了!

在 React 中,我们通过调用 this.state.name 来引用同一份数据。 现在关键的区别在于我们不能简单地写 this.state.name='John',因为 React 做了限制来防止这种简单、无忧无虑的 mutate。 所以在 React 中,我们会使用 this.setState({name:'John'}) 的方式来编写。

虽然这基本上与我们在 Vue 中实现的相同,但是额外的写入是因为 Vue 基本上在每次更新数据时都会合并自己的 setState 版本。 简而言之,React 需要 setState 并传入需要更新的内部数据,而 Vue 假设当你把更新的值传入 data 对象时,你是想更新它的。那么为什么 React 不愿意这样做,为什么还需要 setState 呢? 让 Revanth Kumar 来为我们解释下:

“这是因为 React 希望在状态发生变化时重新运行某些生命周期钩子,[如] componentWillReceiveProps,shouldComponentUpdate,componentWillUpdate,render,componentDidUpdate。 当你调用 setState 函数时,它会知道状态已经改变了。 如果你直接改变状态,React 将需要做更多工作来跟踪更改以及运行生命周期钩子等等。所以为了简单起见,React 使用 setState。“

现在我们已经完成了 mutations,让我们研究下如何在我们的 To Do 应用中添加新项目,以深入了解细节。

 

 

如何创建新的 To Do 项

 

 

 

React:

 

React 是如何做的?

在 React 中,我们的输入字段有一个叫 value 的属性。 这个值通过使用几个函数自动更新,这些函数结合起来会创建一个非常类似于双向绑定的东西(如果你以前从未听说过这个,你可以看看之后的 How did Vue do that 部分)。 我们通过在 input 上添加一个 onChange事件监听器来创建这种形式的双向绑定。 我们简单看一下 input 字段,以便你了解发生了什么:

只要 input 框的值发生更改,handleInput 函数就会运行。 它会将 input 框中的任意输入更新到 state 中的 todo。 这个函数看起来像这样:

现在,只要用户按下页面上的 + 按钮添加新 item,createNewToDoItem 函数就会运行 this.setState 并向其传递一个函数。 这个函数接收两个参数,第一个是来自状态对象的 list数组,第二个是 todo(由 handleInput 函数更新)。 该函数返回一个新对象,该对象包含之前的整个 list,然后在其末尾添加 todo。 整个列表是通过使用扩展运算符添加的(如果你之前没有看过这个 ES6 语法,Google 一下吧)。

最后,我们将 todo 设置为空字符串,它会自动更新 input 框中的值。

 

Vue:

 

Vue 是如何做的?

在 Vue 中,我们的 input 框有一个名为 v-model 的指令。 它允许我们做一些称为双向绑定的事情。 我们先看看 input 框,然后解释下发生了什么:

V-Model 将此字段的输入绑定到名为 toDoItem 的 data 对象中的 key。 当页面加载时,toDoItem 会被置为空字符串,如 todo: ''。 如果 todo 非空,例如 todo: ‘add some text here’,我们的 input 框将加载‘add some text’。 无论如何,回到将其作为空字符串,我们在输入字段中输入的任何文本都将绑定到 todo 的值。 这正是双向绑定(input 可以更新 data 对象,data 对象可以更新 input)。

回到前面的 createNewToDoItem() 代码块,我们看到我们将 todo 的内容 push 到 list 数组中,然后将 todo 更新为空字符串。

 

 

 

如何删除列表数据?

 

 

 

React:

 

React 是如何做的?

虽然 deleteItem 函数位于 ToDo.js 内部,但我可以直接在 ToDoItem.js 中引用它,首先将deleteItem() 函数作为 <ToDoItem /> 上的 prop 传递:

首先将该功能传递给子组件,使其可以被访问。 你可以看到我们也绑定了 this 以及传递了 key 参数,因为 key 是函数将用于区分 ToDoItem 在单击时尝试删除的内容。 然后,在ToDoItem 组件内部,我们执行以下操作:

我需要做的就是引用一个位于父组件内部的函数来引用 this.props.deleteItem

 

Vue:

 

Vue 是如何做的?

Vue 的方法稍有不同。 我们基本上要做三件事:

首先,在我们想要调用函数的元素上:

然后我们必须创建一个 emit 函数作为子组件内部的方法(在本例中为 ToDoItem.vue),如下所示:

除此之外,你会发现我们在 ToDo.vue 中引入 ToDoItem.vue 时实际引用了一个函数

这就是所谓的自定义事件监听器。 它会监听任何使用 'delete' 字符串触发 emit 的操作。 如果监听到,它会触发一个名为 onDeleteItem 的函数。 此函数位于 ToDo.vue 内部,而不是ToDoItem.vue。 如前所述,此函数只是过滤 data 对象内的 todo 数组,以删除被点击的 item。

这里也值得注意的是,在 Vue 示例中,我可以简单地在 @click 监听器中编写 $emit 部分,如下所示:

这会将步数从 3 减少到 2,这仅仅取决于个人偏好。

简而言之,React 中的子组件可以通过 this.props 访问父组件方法(假设你正在传递 props,这是相当标准的做法,你会在其他 React 示例中遇到许多次),而在 Vue 中, 你必须从子组件中触发由父组件所有的事件。

 

 

 

如何传递事件监听器?

 

 

React:

简单事件(如点击事件)的事件监听器是直截了当的。 以下是我们如何为创建新 ToDo item 的按钮创建 click 事件的示例:

这里非常简单,就像我们使用原生 JS 处理内联 onClick 一样。 正如 Vue 部分所述,在按下回车按钮的情况下设置事件监听器就需要花点时间了。 我们可以在 input 标签中处理一下 onKeyPress 事件,如下:

只要它识别出按下了 '回车(Enter)' 键,这个函数就会触发 createNewToDoItem 函数,如下所示:
 

 

Vue:

在 Vue,它是超级直接的。 我们只使用 @ 符号,然后使用我们想要事件监听器的类型。 例如,要添加 click 事件侦听器,我们可以这样:

注意:@click 实际上是 v-on: click 的简写。 Vue 事件监听器的一个很酷的事情是,在它之后我们可以链式调用许多方法,例如 .once,它可以防止事件监听器被多次触发。 在编写用于处理键击的特定事件侦听器时,还有一些快捷方式。 我发现在按下回车按钮的情况下,在 React 中创建一个事件监听器需要花费很长时间来创建新的 ToDo item。而在Vue,我能够简单地这样写:

 

 

 

如何向子组件传递数据?

 

 

 

React:

在 react 中,我们将 props 传递到子组件。 如:

在这里,我们看到两个传递给 ToDoItem 组件的 props。 从现在开始,我们就可以通过 this.props 在子组件中引用它们了。 因此,要访问 item.todo prop,我们只需调用 this.props.item。

 

Vue:

在 Vue 中,我们将 props 传递到子组件。 如:

完成后,我们将它们传递给子组件中的 props 数组,如 props: ['todo']。 然后可以通过他们的名字在子组件中引用它们 - 所以在我们的例子中,'todo'。

 

 

如何将数据发送回父组件?

 

 

React:

我们首先将函数传递给子组件,方法是在我们调用子组件的位置将其引用为 prop。 然后,我们通过引用 this.props.whateverTheFunctionIsCalled,通过任何方式(例如 onClick)添加对子函数的调用。 然后,这将触发位于父组件中的函数。 我们可以在“如何从列表中删除”一节中看到整个过程的示例。

 

Vue:

在我们的子组件中,我们只需编写一个函数,将一个值发送回父函数。 在我们的父组件中,我们编写一个函数来侦听何时 emit 该值,然后可以触发函数调用。 我们可以在“如何从列表中删除”一节中看到整个过程的示例。

 

 

大功告成!

我们研究了如何添加,删除和更改数据,将数据以表单 props 形式从父组件传递到子组件,以及以事件侦听器的形式将数据从子组件发送到父组件。 当然,在 React 和 Vue 之间存在许多其他的小差别,但希望本文的内容能作为理解两个框架如何处理东西的基础。

 

Github links to both apps:

Vue ToDo: https://github.com/sunil-sandhu/vue-todo

React ToDo: https://github.com/sunil-sandhu/react-todo

 

英文原文:
https://medium.com/javascript-in-plain-english/i-created-the-exact-same-app-in-react-and-vue-here-are-the-differences-e9a1ae8077fd

本文转载自:https://mp.weixin.qq.com/s?__biz=MzU0Nzk1MTg5OA==&mid=2247484217&idx=1&sn=edf6301ea61638f184ba518...

共有 人打赏支持
粉丝 4
博文 130
码字总数 31392
作品 0
浦东
私信 提问
Vue vs React: Javascript 框架之战

正如我们之前提到的,WordPress 的核心团队正争论着为应该将哪款(前端框架)加入现在的架构之中。目前看来,暂时脱颖而出的是React与Vue.js,社区中的很多成员正权衡着这两款框架的利弊。 ...

技术小能手
07/23
0
0
用 React 和 Vue 创建了两个完全相同的应用后,发现了这些差异

译者 jonjia 爱贝睿技术团队 在工作中使用 Vue 一段时间后,对它的工作原理有了相当深入的了解。然而,我很想知道篱笆另一边的草地是什么样 - React。 我已经阅读了 React 文档,也观看了一些...

爱贝睿技术团队
08/03
0
0
JavaScript 框架对比及案例(React、Vue 及 Hyperapp)

在我的上一篇文章中,我试图解释为什么我认为 Hyperapp 是一个 React 或 Vue 的可用替代品,原因是,我发现它易于起步。许多人批评这篇文章,认为它自以为是,并没有给其它框架一个展示自己的...

04%
08/23
0
0
Vue 与Angular、React框架的对比,你会学哪个?

首先,我们先了解什么是MVX框架模式? MVX框架模式:MVC+MVP+MVVM 1.MVC:Model(模型)+View(视图)+controller(控制器),主要是基于分层的目的,让彼此的职责分开。 View通过Controller来和M...

阿K1225
10/29
0
0
关于Vue和React区别的一些笔记

这篇文章记录我在使用Vue和React的时候,对他们的不同之处的一些思考,不仅局限于他们本身,也会包括比如 等经常搭配使用的工具。因为涉及到的内容很多,可能下面的每一个点都能写成一篇文章...

言川
07/30
0
0

没有更多内容

加载失败,请刷新页面

加载更多

区块链安全 - 以太坊短地址攻击

1 基础知识 EVM虚拟机在解析合约的字节码时,依赖的是ABI的定义,从而去识别各个字段位于字节码的什么地方。关于ABI,可以阅读这个文档: https://github.com/ethereum/wiki/wiki/Ethereum-C...

HiBlock
18分钟前
0
0
自定义函数及内部函数

变量的作用域 局部变量 global $Global及其他超全局数组 静态变量 仅初始化赋值 保留于内存直到response才销毁 global和static变量的区别 global:局部变量全局话 static:定义静态局部变量 函...

关元
19分钟前
0
0

中国龙-扬科
31分钟前
1
0
python包

https://www.lfd.uci.edu/~gohlke/pythonlibs/

陆朋
42分钟前
1
0
一文弄懂“分布式锁”,一直以来你的选择依据正确吗?

本文主要会关注的问题是“分布式锁”的问题。 多线程情况下对共享资源的操作需要加锁,避免数据被写乱,在分布式系统中,这个问题也是存在的,此时就需要一个分布式锁服务。 常见的分布式锁实...

Java干货分享
49分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部