你是否尝试过使用前端主流框架 Vue.js 和 React 来创建同一个 App?相比之下,哪种更好呢?今天在WEB明教社区看到这样一篇文章,分享给大家,如果对大家有帮助,请给个小红心,搬砖不易.......

众所周知,Vue 和 React 都是目前非常著名的前端框架。我在工作中经常使用 Vue,因此我对它有很深入的了解。同时,我也对 React 充满了好奇,想要学习一下,一探究竟。

于是我阅读了 React 文档并观看了一些视频教程,虽然这些资料很不错,但是我真正想了解的是 React 与 Vue 之间的不同之处。所谓“不同之处”,我并非想知道它们是否都具有虚拟 DOMS 或者它们如何渲染页面,而是希望有人能够从代码的角度解释这两者之间的差异。我想找到一篇解释这些差异的文章,以便 Vue 或者 React 的初学者可以更好地理解它们两者之间的差异。

很遗憾,我并未找到一篇这样的文章。于是我意识到必须自己动手来比较 Vue 与 React 之间的异同。在我自力更生的过程中,我用这篇文章记录下了具体过程。

1. 目标

我将会构建一个标准的待办事项应用程序,允许用户添加和删除列表中的项目。这两个应用程序都使用默认的 CLI(command-line interface,命令行界面) 构建,React 使用 create-react-app,Vue 使用 vue-cli。

两个应用程序的外观如下:

两个应用程序的 CSS 代码几乎一样,但这些代码的位置存在差异。考虑到这一点,我们来看看这两个应用程序的文件结构:

你会发现它们的结构几乎完全相同。唯一的区别在于 React App 拥有三个 CSS 文件,而 Vue App 中没有 CSS 文件。这是因为 React 的 create-react-app 组件需要一个附带文件来保存其样式,而 Vue CLI 采用全包方法,其样式在实际组件文件中声明。

两种不同的策略得到的结果是一样的,相信开发者很快能够掌握这两种不同的策略。开发者可以根据自己的偏好做出选择,你会听到开发社区关于如何构建 CSS 的大量讨论。以上,我们遵循两个 CLI 列出了代码结构。

在我们进一步讨论之前,先快速看一下典型的 Vue 和 React 组件的外观:

左侧为 Vue,右侧为 React

现在让我们正式开始,深入其中的细节!

2. 如何修改数据

首先,我们需要明白“修改数据”的意思是什么。它听起来有些学术,但实际上很简单,就是把我们已经存储好的数据进行更改。比如,如果我们想把一个人的名字变量从“Jhon”改为“Mark”,我们就需要执行“修改数据”的操作。在这一点上,React 和 Vue 的处理方式有所区别。Vue 本质上会创建一个数据对象,其中的数据可以自由更改;React 则创建一个状态对象,更改数据需要一些额外的操作。React 之所以需要额外的操作有着自己的理由,稍后我会深入介绍。在此之前,我们先看看 Vue 中的数据对象和 React 中的状态对象:

Vue 数据对象

React 状态对象

从图中可以看出,我们传入了相同的数据,但它们的标记方法不同。因此,将初始数据传递到组件的方式非常相似。但正如我们提到的那样,在两个框架中更改数据的方式有所不同。

假设我们有一个名为 name: ‘Sunil’ 的数据元素。

在 Vue 中,我们通过调用 this.name 来引用它。我们也可以通过调用 this.name ='John' 来更新它。这样一来,名字就被成功改为了 “Jhon”。

在 React 中,我们通过调用 this.state.name 来引用同一段数据。现在关键的区别在于,我们不能简单地写成 this.state.name ='John',因为 React 有限制机制,它会阻止这种简单的修改方式。在 React 中,我们需要这样写:this.setState({name:'John'})。

虽然这基本上与我们在 Vue 中实现的结果一样,但是 React 的操作更为繁琐,那是因为 Vue 在每次更新数据时默认组合了自己的 setState 版本。 简单来说就是,React 需要 setState,然后更新其内部数据,而对于 Vue 来说,当你更新数据对象的值时它就默认了你的更改意图。 那么为什么 React 没有进行简化,为什么需要 setState 呢? Revanth Kumar 对此做出了解释:

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

现在我们知道如何更改数据了,接下来看看如何在待办应用程序中添加新的事项。

3. 添加新的待办事项

React 的实现方法

createNewToDoItem = () => {this.setState( ({ list, todo }) => ({list: [...list,{todo}],todo: ''}));};

在 React 中,我们的输入字段有一个名为 value 的属性。这个 value 通过使用几个函数自动更新,这些函数绑定在一起以创建双向绑定。我们通过在输入字段上附加一个 onChange 事件监听器来创建这种形式的双向绑定。看看代码,一探究竟:

<input type="text" value={this.state.todo} onChange={this.handleInput}/>

只要输入字段的值发生更改,handleInput 函数就会运行。它通过将状态对象设置为输入字段中的任何内容来更新状态对象内的 todo。handleInput 函数如下:

handleInput = e => {this.setState({todo: e.target.value});};

现在,只要用户按下页面上的 + 按钮添加新项目,createNewToDoItem 函数就会运行 this.setState 并向其传递一个函数。该函数有两个参数,第一个是来自状态对象的整个列表数组,第二个是由 handleInput 函数更新的todo。然后该函数返回一个新对象,该对象包含之前的整个列表,并在其末尾添加todo。整个列表是通过使用扩展运算符添加的。

最后,我们将 todo 设置为空字符串,它会自动更新输入字段中的 value。

Vue 的实现方法

createNewToDoItem() {this.list.push({'todo': this.todo});this.todo = '';}

在 Vue 中,我们的输入字段中有一个名为 v-model 的句柄。这实现了**双向绑定。输入字段代码如下:

<input type="text" v-model="todo"/>

V-Model 将输入字段的内容绑定到名为 toDoItem 的数据对象的键(key)上。当页面加载时,我们将 toDoItem 设置为空字符串,比如:todo:' '。如果已经存在数据,例如 todo:'添加文本处',输入字段将加载添加文本处的输入内容。无论如何,将其作为空字符串,我们在输入字段中键入的任何文本都会绑定到 todo。这实际上是双向绑定(输入字段可以更新数据对象,数据对象可以更新输入字段)。

因此,回顾前面的 createNewToDoItem() 代码块,我们将 todo 的内容存放到列表数组中 ,然后将 todo 改为空字符串。

4. 删除待办事项

React 的实现方法

deleteItem = indexToDelete => {this.setState(({ list }) => ({list: list.filter((toDo, index) => index !== indexToDelete)}));};

尽管 deleteItem 函数位于 ToDo.js 文件中,但是从 ToDoItem.js 文件中引用它也很容易,将 deleteItem() 函数作为 上的 prop 传递:

<ToDoItem deleteItem={this.deleteItem.bind(this, key)}/>

这会将该函数传递给子组件,使其可以访问。我们绑定了 this 并传递 key 参数,当用户点击删除项时,函数通过 key 区分用户点击的是哪一条 ToDoItem 。然后,在ToDoItem 组件内部,我们执行以下操作:

<div className=”ToDoItem-Delete” onClick={this.props.deleteItem}>-</div>

想要引用位于父组件内部的函数,只需引用 this.props.deleteItem 即可。

Vue 的实现方法

onDeleteItem(todo){this.list = this.list.filter(item => item !== todo);}

Vue 的实现方法稍有不同,我们需要做到以下三点:

Step 1:首先,在元素上调用函数:

<div class=”ToDoItem-Delete” @click=”deleteItem(todo)”>-</div>

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

deleteItem(todo) {this.$emit('delete', todo)}

Step 3:之后,你会发现,当我们添加 ToDo.vue的 ToDoItem.vue 时,实际上引用了一个函数:

<ToDoItem v-for="todo in list" :todo="todo" @delete="onDeleteItem" // <-- this :):key="todo.id" />

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

在 Vue 示例中还需要注意的是,我们可以在 @click 侦听器中编写 $emit 部分,这样更加简单,如下所示:

<div class=”ToDoItem-Delete” @click=”$emit(‘delete’, todo)”>-</div>

如果你喜欢,这样做可以把 3 步减少到 2 步。

React 中的子组件可以通过 this.props 访问父函数,而在 Vue 中,你需要从子组件中发出事件,父组件来收集事件。

5. 如何传递事件监听器

React 的实现方法

事件监听器处理简单事件(比如点击)非常直接。我们为待办事项创建了点击事件,用于创建新的待办事项,代码如下:

<div className=”ToDo-Add” onClick={this.createNewToDoItem}>+</div>.

非常简单,就像使用 vanilla JS 处理内联 onClick 一样。正如前文所述,只要按下回车按钮,设置事件监听器就需要花费更长的时间。这需要输入标签处理 onKeyPress 事件,代码如下:

<input type=”text” onKeyPress={this.handleKeyPress}/>.

该函数只要识别到'enter'键被按下,它就会触发 **createNewToDoItem** 函数,代码如下所示:

handleKeyPress = (e) => {if (e.key === ‘Enter’) {this.createNewToDoItem();}};

Vue 的实现方法

Vue 的事件监听器更加直接。我们只需要使用一个简单的 @ 符号,就可以构建出我们想要的事件监听器。例如,想要添加 click 事件监听器,代码:

<div class=”ToDo-Add” @click=”createNewToDoItem()”>+</div>

注意:@click 实际上是 v-on:click 的简写。Vue 事件监听器很强大,你可以为其选择属性,例如 .once 可以防止事件监听器被多次触发。此外,它还包含很多快捷方式。按下回车按钮时,React 就需要花费更长的时间来创建事件监听器,从而创建新的 ToDo 项目。在 Vue,代码如下:

<input type=”text” v-on:keyup.enter=”createNewToDoItem”/>

6. 如何将数据传递给子组件

React 的实现方法

在 React 中,我们将 props 传递到子组件的创建处。比如:

<ToDoItem key={key} item={todo} />

此处我们向 ToDoItem 组件传递了两个 prop。之后,我们可以在子组件中通过 this.props 引用它们。因此,想要访问 item.todo prop,我们只需调用this.props.item 。

Vue 的实现方法

在 Vue 中,我们将 props 传递到子组件创建处的方式如下:

<ToDoItem v-for="todo in list" :todo="todo":key="todo.id"@delete="onDeleteItem" />

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

7. 如何将数据发送回父组件

React 的实现方法

我们首先将函数传递给子组件,方法是在我们调用子组件时将其引用为 prop。然后我们通过引用
this.props.whateverTheFunctionIsCalled,为子组件添加调用函数,例如 onClick。然后,这将触发父组件中的函数。删除待办事项一节中详细介绍了整个过程。

Vue 的实现方法

在子组件中我们只需编写一个函数,将一个值发送回父函数。在父组件中编写一个函数来监听子组件何时发出该值的事件,监听到事件之后触发函数调用。同样,删除待办事项一节中详细介绍了整个过程。

8. 总结

我们研究了添加、删除和更改数据,以 prop 形式从父组件到子组件传递数据,以及通过事件监听器的形式将数据从子组件发送到父组件。当然,React 和 Vue 之间存在一些小差异,希望本文的内容有助于理解这两个框架。

本文来源:WEB明教光明顶社区(https://web.xingruanedu.com/thread-42-1-1.html)

监听输入 vue_深度对比vue与react创建APP的差别,值得收藏相关推荐

  1. textfield监听输入汉字数量

    2019独角兽企业重金招聘Python工程师标准>>> ###textfield监听输入汉字数量 首先我们给textfield添加一个事件,当文字改变的时候调用 [self.name ...

  2. Android EditText缴获与监听输入事件

    Android EditText缴获与监听输入事件 Android EditText截获与监听输入事件 预期目标:如下图,输入框中每输入一个字符,下面的TextView可以迅速的显示出来输入框中的内容 ...

  3. 微信小程序哪个能唱歌_可以听歌的微信小程序有哪些?推荐几个值得收藏的!...

    不知道大家是否跟我一样都喜欢听音乐,比如心情不好,工作压力大,或者生活上的压迫,就会感觉整个人都挺丧.心事很少告诉别人,担心人家当笑话一样听.所以只有静下来听听歌,平复一下心情,今天全网小程序门户网站 ...

  4. 纯js监听滚动条到底部(vue版)

    项目中,因为数据量过大,为提高页面性能,采用页面滑动 滚动条到底部的时候再进行数据请求分页,这边给大给个核心,结合vue的生命周期用纯javascript写的一个监听函数 第一个我们需要知道几个属性值 ...

  5. 监听关闭页面事件 ajax,Vue 实现监听窗口关闭事件,并在窗口关闭前发送请求

    网上很多博客说监听窗口关闭事件使用window.beforeunload,但是这个监听事件也会在页面刷新的时候执行,经过百度和自己的实际测试, 终于解决了这个问题,代码如下: mounted() { ...

  6. iOS 自定义搜索框实时监听输入的内容变化

    产品需求:点击搜索框,弹出键盘,当输入内容发生变化时,需要实时匹配与输入内容相关的产品,列表展示,让用户去选择:类似于淘宝和京东的搜索功能. 拿到需求的时候觉得这个应该挺简单的啊,苹果这么强大,这些功 ...

  7. window.onresize监听窗口宽度踩坑 vue

    踩坑方法 vue组件监听页面宽度变化最近网上比较常用的方法 此方法可以实现监听窗口变化 但是! 不支持组件重复循环使用 不支持组件重复循环使用 不支持组件重复循环使用 重要的事情说三遍 ! 此方法在多 ...

  8. UITextField实时监听输入文本的变化

    开始用如下代理方法发现只能监听到变化后的前一位 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NS ...

  9. C++之epoll监听输入(替代select)

        在linux的网络编程中,很长的时间都在使用select来做事件触发.在linux新的内核中,有了一种替换它的机制,就是epoll.相比于select,epoll最大的好处在于它不会随着监听f ...

最新文章

  1. cdatabase读取excel第一行数据_“蟒蛇”py对Excel的读取——数据操作用它,老板都得重新认识你...
  2. 带你重读Youtube深度学习推荐系统论文,惊为神文
  3. 【栈和队列】数据结构02-(java实现)
  4. AWS Lambda 开发企业微信消息机器人
  5. Linux Capabilities 入门教程--进阶实战篇
  6. C语言数据结构之顺序队列
  7. python暴力破解六位密码(数字和大小写字母)
  8. 运动会加油稿计算机学院150字,学校运动会加油稿150字10篇
  9. 再见,拼多多!再见,黄铮!
  10. mysql大于等于between比较_MySQL范围查询优化,Between与大于等于对比及优化
  11. U3D教程多摄像机协同运行
  12. 文章:Mapping regulatory variants controlling gene expression in drought response and tolerance
  13. c#winform之TextBox
  14. Xshell官方免费版
  15. JavaWeb - 小米商城 :首页商品分类展示
  16. 程序员基础内功夯实——数据结构篇
  17. blender 绘制离散顶点, SMPL骨架绘制
  18. WADISWAT数据处理
  19. linux下swf播放工具
  20. 竞争性谈判和竞争性磋商的区别

热门文章

  1. android 电池栏的高度,Android如何取得状态栏、任务栏高度
  2. 初三学生多会筹备计算机中考考试,2020年的初中生注意,中考将会发生这几大变化,最好提前准备...
  3. centos7 r语言安装_R 和 RStudio 的安装及 R Profile 的配置 amp; 初识 R 语言数据爬取...
  4. 头像裁剪上传插件php,PHP+ajaxfileupload+jcrop插件完美实现头像上传剪裁
  5. python进阶(十七)xml(下)
  6. Python中执行外部命令
  7. 硬件——STM32 , 录音
  8. leetcode 81 Search in Rotated Sorted Array II ----- java
  9. hashicorp/consul
  10. [Asp.net 5] DependencyInjection项目代码分析4-微软的实现(5)(IEnumerable补充)