我用React和Vue构建了同款应用,来看看哪里不一样

文章图片
作者丨SunilSandhu
译者丨王强
策划丨小智
几年前 , 我决定试着分别在React和Vue中构建一个相当标准的ToDo(待办事项)应用 。 这两个应用都是使用默认的CLI构建的(React的create-react-app和Vue的vue-cli) 。 我想尽量保持中立 , 通过这样的例子来告诉大家这两种技术执行特定任务时是怎样做的 。
当ReactHooks发布时 , 我为这篇文章更新了“2019版” , 用函数式Hooks取代了类组件 。 随着Vue3及其组合(Composition)API的发布 , 现在是时候更新这篇文章的“2020版”了 。
先来大致看一下两款应用的外观:

文章图片
两款应用的CSS代码完全相同 , 但代码所处的位置有所不同 。 记住这一点 , 接下来让我们看一下它们的文件结构:

文章图片
你会发现它们的结构也几乎相同 。 唯一的区别是React应用有两个CSS文件 , 而Vue应用没有任何CSS文件 。 这是因为在create-react-app中 , 默认每个React组件都会附带一个单独文件来保存其样式 , 而VueCLI用单一的文件来为默认组件包含HTML、CSS和JavaScript 。
最后它们俩都达成了同样的目标 , 也没什么可多说的 , 因为在React或Vue中你都不能改变文件结构 。 选择哪个确实取决于个人喜好 。 开发社区关于CSS的结构化方式这个话题有大量的讨论 , 尤其是React这块 , 因为有许多CSS-in-JS解决方案 , 诸如样式化组件和emotion等 。 顺便说一句 , CSS-in-JS就是字面上的意思 。 虽然这些都很有用 , 但这里我们只用两边的CLI给出的结构 。
在进一步深入之前 , 我们先来看一下典型的Vue和React组件长什么样:
典型的React文件:

文章图片
典型的Vue文件:

文章图片
看过之后我们来深入了解细节吧!
我们如何突变数据?
首先 , “突变数据”到底是什么意思呢?听起来是不是有点高深?其实它基本上就是指更改我们已存储的数据 。 如果我们想将一个人名的值从John更改为Mark , 我们就是在“突变“这份数据 。 这就是React和Vue之间的关键区别所在 。 Vue本质上创建了一个数据对象 , 可以在其中自由更新数据 , 而React通过所谓的状态Hook来处理数据突变 。
从下面的图片中可以看到两者的设置 , 然后我们会具体说明:
React状态:

文章图片
Vue状态:

文章图片
于是你看到我们将相同的数据传递给了两者 , 但各自的结构有所不同 。
在React中 , 至少从2019年开始 , 我们一般会通过一系列Hooks处理状态 。 你可能以前没接触过这种概念 , 一开始它看起来可能有点奇怪 。 它的工作机制基本上是这个样子:
假设我们要创建一个待办事项列表 , 我们可能需要创建一个名为list的变量 , 它可能需要接收一个由字符串或对象组成的数组(比如说给每个todo字符串一个ID或其他一些东西) 。 我们需要写的代码是 。 这里我们用的就是React里面的Hook , 称为useState 。 它本质上是让我们能够在组件中保留局部状态 。
另外 , 你可能已经注意到我们在useState()内部传入了一个空数组[] 。 放在其中的是我们希望list最初设置的内容 , 这里我们希望是一个空数组 。 但从上图可以看到 , 我们在数组内传入了一些数据 , 这些数据最后成了list的初始化数据 。 想知道setList是做什么的?稍后会进一步说明!
在Vue中 , 通常会将组件的所有突变数据放置在一个setup()函数内 , 该函数返回一个对象 , 其中包含要公开的数据和函数(就是那些你要在应用中使用的东西) 。 你会注意到 , 应用中的每个状态数据(也就是我们希望能够突变的数据)都包装在一个ref()函数内部 。 这个ref()函数是我们从Vue导入的 , 可让我们的应用在这些数据更改/更新时完成更新 。 简而言之 , 如果你想在Vue中创建突变数据 , 请为ref()函数分配一个变量 , 并在其中放入默认数据 。
如何在应用中引用突变数据?
假设我们有一些数据名为name , 被分配了Sunil值 。
在React中 , 由于我们使用useState()创建了较小的状态 , 因此很可能已经用创建了一些东西 。 在应用中 , 我们将简单地调用name来引用同一段数据 。 这里的主要区别在于我们不能简单地写上 , 因为React有一些限制来预防这种简单且无所顾忌的突变 。 在React中 , 我们要写成 。 这里用到了setName 。 在中 , 它创建两个变量 , 一个变量变为 , 而第二个constsetName被分配了一个函数 , 该函数使name可以用新值重新创建 。
在Vue中 , 它位于setup()函数内部 , 并且被称为 。 在应用中 , 我们将调用name.value来引用它 。 如果要使用在ref()函数内部创建的值 , 我们将在变量上寻找.value而不是简单地调用该变量 。 换句话说 , 如果我们想要一个持有状态的变量值 , 我们将寻找name.value而不是name 。 如果要更新name的值 , 可以通过更新name.value来完成 。 例如 , 假设我想将我的名字从Sunil更改为John,可以写来做到这一点 。
实际上 , React和Vue在这里做的是同样的事情 , 也就是创建可以更新的数据 。 Vue本质上会在每次更新一条包装在ref()函数内的数据时默认结合它自己的name和setName版本 。 React要求你使用内部值调用setName()来更新状态 , 而如果你曾尝试更新数据对象内部的值 , Vue就会假设你要这么做 。 那么为什么React会费劲地将值与函数分开 , 还要使用useState()呢?这是因为当状态改变时 , React希望重新运行某些生命周期Hooks 。 在我们的例子中 , 当你调用setName()时 , React会知道有些状态已更改 , 所以可以运行它们的生命周期Hooks 。 如果你直接改变状态 , React将不得不做更多的工作来跟踪更改以及要运行的生命周期Hooks等 。
现在我们已经搞明白了数据突变 , 接下来看看在两个ToDo应用中添加新项目的方法 。
我们如何创建新的待办事项?
React:
在React里是怎么做的?
在React中 , 我们的输入字段有一个名为value的属性 。 每次通过onChange事件侦听器更改它的值时 , 都会自动更新此值 。 JSX(基本上是HTML的变体)如下所示:
每次更改值时 , 它都会更新状态 。 handleInput函数如下所示:
现在 , 每当用户按下页面上的+按钮添加新项目时 , 都会触发createNewToDoItem函数 。 我们再来看一下这个函数 , 搞清楚具体发生了什么:
本质上 , newId函数是在创建一个新ID , 该ID将提供给我们的新toDo项目 。 newToDo变量是一个对象 , 有一个id键 , 其值由newID确定 。 它还有一个text键 , 其值由toDo确定 。 这个toDo就是输入值更改时要更新的那个toDo 。
setList函数到此为止 , 然后我们传入一个包含整个list以及新创建的newToDo的数组 。
你可能觉得…list看起来很奇怪:开头的三个点称为spread运算符 , 负责将list中的所有值作为单独的项目传递 , 而不是简单地把所有项目打包在一起作为数组传递 。 感觉有些糊涂吗?那我强烈建议你仔细阅读spread运算符的相关介绍 , 因为它很有用!
最后我们运行setToDo()并传入一个空字符串 。 这样我们的输入值为空 , 可以输入新的toDo了 。
Vue:
在Vue里是怎么做的?
在Vue中 , 我们的input字段有一个称为v-model的句柄 。 这使我们能够执行称为双向绑定的操作 。 下面来看一下input字段 , 搞清楚到底发生了什么:
V-Model将这个字段的输入与我们在setup()函数上创建的一个变量相关联 , 然后公开为一个返回对象内的键 。 到目前为止我们还没有介绍对象返回的内容 , 所以先说一下 , 这是我们从ToDo.vue内部的setup()函数返回的内容:
这里 , list、todo和showError是我们的有状态值 , 而其他所有内容都是我们希望能在应用其他位置调用的函数 。 在页面加载时 , 我们必须将todo设置为一个空字符串 , 例如:consttodo=ref("") 。 如果其中已经有一些数据 , 例如consttodo=ref("addsometexthere"):我们的输入字段将在内部已有addsometexthere的情况下加载 。 不管怎样 , 回到空字符串的状态 , 无论我们在输入字段中键入什么文本都必须绑定到todo.value 。 这实际上就是双向绑定——输入字段可以更新ref()值 , 反过来后者也可以更新输入字段 。
回顾一下前面的createNewToDoItem()代码块 , 可以看到 , 我们将todo.value的内容推送到list数组中 , 然后将前者更新为一个空字符串 。
我们还使用了与React示例中相同的newId()函数 。
如何从列表中删除项目?
【我用React和Vue构建了同款应用,来看看哪里不一样】React:
推荐阅读
- 脑梗死|脑梗死和喝酒有没有关系呢?爱喝酒的朋友,应该看看
- 教你自制岩烧乳酪
- 红豆和玉米面是绝配,一个做皮一个做馅,包好入锅一蒸,特香
- 大脑|你的大脑和心理究竟是什么关系?
- 猪血和此菜才是绝配,5块钱炒一盘,补铁助消化,我家一周吃2次
- 春天,要多吃这肉,比猪肉便宜比羊肉温和,营养滋补更解馋
- 烙饼时,别再用凉水和开水了,用它,又软又香还出层,放凉也不硬
- 乙肝|和乙肝患者一起吃饭到底会不会被传染?
- 海带和什么炖是绝配?
- 冬天|“我今年23岁,不敢和人牵手拥抱,都是因为这个恼人的玩意儿”
