vue和react相同点_我在React和Vue中创建了相同的应用程序。 这是区别。

vue和react相同点

by Sunil Sandhu

由Sunil Sandhu

我在React和Vue中创建了相同的应用程序。 这是区别。 (I created the same app in React and Vue. Here are the differences.)

Having used Vue at my current workplace, I had a fairly solid understanding of how it all worked. I was, however, curious to know what the grass was like on the other side of the fence — the grass in this scenario being React.

在我目前的工作场所使用Vue之后,我对Vue的工作原理有了相当扎实的了解。 但是,我很好奇要知道栅栏另一侧的草是什么样的,在这种情况下,草是React。

I’d read the React docs and watched a few tutorial videos and, while they were great and all, what I really wanted to know was how different React was from Vue.

我阅读了React文档并观看了一些教程视频,尽管它们很棒,但我真正想知道的是ReactVue有何不同。

By “different”, I didn’t mean things such as whether they both had virtual DOMS or how they went about rendering pages. I wanted someone to take the time to explain the code and to tell me what was going on! I wanted to find an article that took the time to explain these differences so that someone new to either Vue or React (or Web Development as a whole) could gain a better understanding of the differences between the two.

我所说的“不同”并不是指诸如它们是否都具有虚拟DOMS或它们如何呈现页面之类的东西。 我希望有人花时间解释代码并告诉我发生了什么! 我想找到一篇文章,花一些时间来解释这些差异,以便对VueReact (或整个Web开发)不熟悉的人都能更好地理解两者之间的差异。

But I couldn’t find anything that tackled this. So I came to the realisation that I’d have to go ahead and build this myself in order to see the similarities and differences. In doing so, I thought I’d document the whole process so that an article on this would finally exist.

但是我找不到解决这个问题的方法。 因此,我意识到我必须继续自己动手构建这个结构,才能看到异同。 这样做的时候,我想我要记录整个过程,以便最后有一篇有关此的文章。

I decided to try and build a fairly standard To Do App that allows a user to add and delete items from the list. Both apps were built using the default CLIs (create-react-app for React, and vue-cli for Vue). CLI stands for Command Line Interface by the way. ?

我决定尝试构建一个相当标准的To Do App,该应用程序允许用户从列表中添加和删除项目。 这两个应用程序都是使用默认的CLI构建的( React的 create-react-appVue的 vue-cli )。 CLI顺便说一句代表命令行界面 。 ?

无论如何,此介绍已经比我预期的要长。 因此,让我们开始快速看一下这两个应用程序的外观: (Anyway, this intro is already longer than I’d anticipated. So let’s start by having a quick look at how the two apps look:)

The CSS code for both apps is exactly the same, but there are differences in where these are located. With that in mind, let’s next have a look at the file structure of both apps:

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

You’ll see that their structures are almost identical as well. The only difference here is that the React app has three CSS files, whereas the Vue app doesn’t have any. This is because, in create-react-app, a React component will have an accompanying file to hold its styles, whereas the Vue CLI adopts an all-encompassing approach where the styles are declared inside the actual component file.

您会发现它们的结构也几乎相同。 唯一的区别是React应用程序具有三个CSS文件,而Vue应用程序没有任何CSS文件。 这是因为,在create-react-app中, React组件将具有一个附带的文件来保存其样式,而Vue CLI采用了一种包罗万象的方法,即在实际的组件文件中声明样式

Ultimately, they both achieve the same thing, and there is nothing to say that you can’t go ahead and structure your CSS differently in React or Vue. It really comes down to personal preference — you’ll hear plenty of discussion from the dev community over how CSS should be structured. For now, we’ll just follow the structure laid out in both CLIs.

最终,它们都达到了相同的目的,没有什么可说的,您不能继续在React或Vue中以不同的方式构造CSS。 这实际上取决于个人喜好-您将听到开发人员社区就CSS的结构如何进行大量讨论。 现在,我们将仅遵循两个CLI中列出的结构。

But before we go any further, let’s take a quick look at what a typical Vue component and React component look like:

但是在进一步介绍之前,让我们快速看一下典型的Vue组件和React组件的外观:

Now that’s out of the way, let’s get into the nitty gritty detail!

既然这已经不成问题了,那就让我们深入了解细节吧!

我们如何突变数据? (How do we mutate data?)

But first, what do we even mean by “mutate data”? Sounds a bit technical, doesn’t it? It basically just means changing the data that we have stored. So if we wanted to change the value of a person’s name from John to Mark, we would be ‘mutating the data’.

但是首先,“突变数据”甚至意味着什么? 听起来有点技术性,不是吗? 基本上,这只是意味着更改我们已存储的数据。 因此,如果我们想将一个人的名字的值从John更改为Mark,我们将“对数据进行变异”。

This is where a key difference between React and Vue lies. While Vue essentially creates a data object, where data can freely be updated, React creates a state object, where a little more legwork is required to carry out updates.

这是React和Vue之间的关键区别所在。 Vue本质上创建了一个可以自由更新数据的数据对象,而React创建了一个状态对象,在状态对象中执行更新需要更多的工作

Now React implements the extra legwork with good reason, and we’ll get into that in a little bit. But first, let’s take a look at the data object from Vue and the state object from React:

现在,React有充分的理由实施了额外的工作,我们将对此进行一些介绍。 但是首先,让我们看一下Vue中的数据对象和React中的状态对象:

So you can see that we have passed the same data into both, but they’re simply labelled differently. So passing initial data into our components is very, very similar. But as we’ve mentioned, how we go about changing this data differs between the frameworks.

因此,您可以看到我们已经将相同的数据传递给了两者,但是它们只是被不同地标记。 因此,将初始数据传递到我们的组件中非常相似。 但是,正如我们已经提到的,在两个框架之间,我们如何更改此数据是不同的。

Let’s say that we have a data element called name: ‘Sunil’.

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

In Vue, we reference this by calling this.name. We can also go about updating this by calling this.name = ‘John’. This would change my name to John. I’m not sure how I feel about being called John, but hey ho, things happen! ?

在Vue中,我们通过调用this.name引用它。 我们还可以通过调用this.name = 'John' 。 这会将我的名字更改为John。 我不确定自己被称为约翰的感觉,但是嘿,事情发生了! ?

In React, we would reference the same piece of data by calling this.state.name. Now the key difference here is that we cannot simply write this.state.name = ‘John’, because React has restrictions in place to prevent this kind of easy, care-free mutation-making. So in React, we would write something along the lines of this.setState({name: ‘John’}).

在React中,我们将通过调用this.state.name引用相同的数据。 现在,这里的主要区别是我们不能简单地编写this.state.name = 'John' ,因为React有适当的限制来防止这种简单,轻松的突变产生。 因此,在React中,我们将按照this.setState({name: 'John'})编写内容。

While this essentially does the same thing as we achieved in Vue, the extra bit of writing is there because Vue essentially combines its own version of setState by default whenever a piece of data gets updated.

尽管这基本上与我们在Vue中实现的功能相同,但是还有很多需要写的内容,因为每当数据更新时,Vue都会默认结合其自己的setState版本。

So in short, React requires setState and then the updated data inside of it, whereas Vue makes an assumption that you’d want to do this if you were updating values inside the data object.

简而言之, React需要setState,然后需要其中的更新数据,而Vue假设如果要更新data对象中的值则需要这样做

Why does React even bother with this, and why is setState even needed? Let’s hand this over to Revanth Kumar for an explanation:

为什么React会为此而烦恼,为什么甚至需要setState? 让我们将其交给Revanth Kumar进行解释:

“This is because React wants to re-run certain life cycle hooks, [such as] componentWillReceiveProps, shouldComponentUpdate, componentWillUpdate, render, componentDidUpdate, whenever state changes. It would know that the state has changed when you call the setState function. If you directly mutated state, React would have to do a lot more work to keep track of changes and what lifecycle hooks to run etc. So to make it simple React uses setState.”
“这是因为当状态改变时,React希望重新运行某些生命周期挂钩,例如componentWillReceiveProps,shouldComponentUpdate,componentWillUpdate,render,componentDidUpdate。 当您调用setState函数时,它将知道状态已更改。 如果直接改变状态,React将不得不做更多的工作来跟踪更改以及要运行的生命周期挂钩等。因此要使其简单,React使用setState。

Now that we have mutations out of the way, let’s get into the nitty gritty by looking at how we would go about adding new items to both of our To Do Apps.

现在,我们已经有了一些变通的方式,让我们看一下如何在两个待办事项中添加新项目。

我们如何创建新的待办事项? (How do we create new To Do Items?)

React: (React:)
createNewToDoItem = () => {
    this.setState( ({ list, todo }) => ({
      list: [
          ...list,
        {
          todo
        }
      ],
      todo: ''
    })
  );
};
React是如何做到的? (How did React do that?)

In React, our input field has a attribute on it called value. This value gets automatically updated through the use of a couple of functions that tie together to create something that closely resembles two-way binding (if you’ve never heard of this before, there’s a more detailed explanation in the How did Vue do that section after this). We create this form of two-way binding by having an additional onChange event listener attached to the input field.

在React中,我们的输入字段具有一个名为value的属性 通过使用几个结合在一起的函数来自动更新此值,以创建类似于双向绑定的东西 (如果您以前从未听说过, Vue的工作原理部分中有更详细的解释)在这之后)。 我们通过将附加的onChange事件侦听器附加到输入字段来创建这种双向绑定形式。

Let’s quickly take a look at the input field so that you can see what is going on:

让我们快速看一下输入字段,以便可以看到发生了什么:

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

The handleInput function is run whenever the value of the input field changes. It updates the todo that sits inside the state object by setting it to whatever is in the input field. This function looks as such:

每当输入字段的值更改时,都会运行handleInput函数。 它通过将状态对象设置为输入字段中的内容来更新位于状态对象内部的待办事项 。 该函数如下所示:

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

Now, whenever a user presses the + button on the page to add a new item, the createNewToDoItem function essentially runs this.setState and passes it a function.

现在,每当用户按下页面上的+按钮添加新项目时, createNewToDoItem 函数本质上运行this.setState并将其传递给函数。

This function takes two parameters, the first being the entire list array from the state object, the second being the todo (which gets updated by the handleInput function). The function then returns a new object, which contains the entire list from before and then adds todo at the end of it. The entire list is added through the use of a spread operator (Google this if you’ve not seen this before — it’s ES6 syntax).

此函数有两个参数,第一个是整个list 状态对象的数组,第二个是todo (由handleInput函数更新)。 然后,该函数返回一个新对象,该对象包含之前的整个list ,然后添加todo 在它的结尾。 整个列表是通过使用传播运算符添加的(如果您以前没有看过,请使用Google this-ES6语法)。

Finally, we set todo to an empty string, which automatically updates the value inside the input field.

最后,我们设置todo 到一个空字符串,该字符串将自动更新输入字段中的

Vue: (Vue:)
createNewToDoItem() {
    this.list.push(
        {
            'todo': this.todo
        }
    );
    this.todo = '';
}
Vue是如何做到的? (How did Vue do that?)

In Vue, our input field has a handle on it called v-model. This allows us to do something known as two-way binding. Let’s just quickly look at our input field, then we’ll explain what is going on:

在Vue中,我们的输入字段具有一个称为v-model的句柄。 这使我们能够执行称为双向绑定的操作 。 让我们快速看一下输入字段,然后说明发生了什么:

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

V-Model ties the input of this field to a key we have in our data object called toDoItem. When the page loads, we have toDoItem set to an empty string, as such: todo: ‘’. If this had some data already in there, such as todo: ‘add some text here’, our input field would load with add some text here already inside the input field.

V模型将此字段的输入与我们在数据对象toDoItem中拥有的键相关联。 页面加载时,我们必须将toDoItem设置为空字符串,例如: todo: '' 。 如果其中已经有一些数据,例如todo: 'add some text here' ,则我们的输入字段将在输入字段内部已经添加一些文本的情况下加载。

Anyway, going back to having it as an empty string, whatever text we type inside the input field gets bound to the value for todo. This is effectively two-way binding (the input field can update the data object and the data object can update the input field).

无论如何,回到它为空字符串后,无论我们在输入字段中键入什么文本,都将绑定到todo的值。 这实际上是双向绑定(输入字段可以更新数据对象,而数据对象可以更新输入字段)。

So looking back at the createNewToDoItem() code block from earlier, we see that we push the contents of todo into the list array and then update todo to an empty string.

因此,回顾一下createNewToDoItem() 前面的代码块,我们看到我们推送了todo的内容 进入list 数组 然后更新todo 到一个空字符串。

我们如何从列表中删除? (How do we delete from the list?)

React: (React:)
deleteItem = indexToDelete => {
    this.setState(({ list }) => ({
      list: list.filter((toDo, index) => index !== indexToDelete)
    }));
};
React是如何做到的? (How did React do that?)

So whilst the deleteItem function is located inside ToDo.js, I was very easily able to make reference to it inside ToDoItem.js by firstly passing the deleteItem() function as a prop on <ToDoItem/> as such:

因此,尽管deleteItem函数位于ToDo.js内, 通过首先传递deleteItem() ,我很容易能够在ToDoItem.js对其进行引用 可以作为<ToDoIte m />的道具,例如:

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

This passes the function down to make it accessible to the child. You’ll see here that we’re also binding this as well as passing the key parameter, as the key is what the function is going to use to differentiate between which ToDoItem we’re attempting to delete when clicked. Then, inside the ToDoItem component, we do the following:

这会将功能向下传递,以使儿童可以使用它。 您将在此处看到,我们还绑定了this参数并传递了key参数,因为key是函数将用来区分单击时试图删除的ToDoItem的功能。 然后,在ToDoItem组件内部,执行以下操作:

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

All I had to do to reference a function that sat inside the parent component was to reference this.props.deleteItem.

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

Vue: (Vue:)
onDeleteItem(todo){
  this.list = this.list.filter(item => item !== todo);
}
Vue是如何做到的? (How did Vue do that?)

A slightly different approach is required in Vue. We essentially have to do three things here:

Vue中需要一种稍微不同的方法。 我们基本上必须在这里做三件事:

Firstly, on the element we want to call the function:

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

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

Then we have to create an emit function as a method inside the child component (in this case, ToDoItem.vue), which looks like this:

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

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

Along with this, you’ll notice that we actually reference a function when we add ToDoItem.vue inside of ToDo.vue:

伴随着这一点,你会发现,我们实际上引用功能 ,当我们添加ToDoItem.vue ToDo.vue内:

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

This is what is known as a custom event-listener. It listens out for any occasion where an emit is triggered with the string of ‘delete’. If it hears this, it triggers a function called onDeleteItem. This function sits inside of ToDo.vue, rather than ToDoItem.vue. As we discussed earlier, it simply filters the todo array inside the data object to remove the item that was clicked on.

这就是所谓的自定义事件侦听器 。 它侦听任何使用字符串'delete'触发发射的情况。 如果听到此消息,它将触发一个名为onDeleteItem的函数。 此函数位于ToDo.vue内部而不是ToDoItem.vue中 。 如前所述,它只是在内部过滤todo 数组 data 对象以删除单击的项目。

It’s also worth noting here that in the Vue example, I could have simply written the $emit part inside of the @click listener, as such:

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

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

This would have reduced the number of steps down from 3 to 2, and this is simply down to personal preference.

这将使步数从3减少到2,而这完全取决于个人喜好。

In short, child components in React will have access to parent functions via this.props (providing you are passing props down, which is fairly standard practice — you’ll come across this loads of times in other React examples). In Vue, on the other hand, you have to emit events from the child that will usually be collected inside the parent component.

简而言之, React中的子组件将可以通过 this.props 访问父函数( this.props是您要传递props,这是相当标准的做法-在其他React示例中,您会遇到很多这种情况)。 另一方面,在Vue中, 您必须从孩子发出事件,这些事件通常将在父组件内部收集

我们如何传递事件监听器? (How do we pass event listeners?)

React: (React:)

Event listeners for simple things such as click events are straightforward. Here is an example of how we created a click event for a button that creates a new ToDo item:

单击事件之类的简单事件的事件侦听器很简单。 这是我们如何为创建新的ToDo项目的按钮创建click事件的示例:

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

Super easy here, and pretty much looks like how we would handle an in-line onClick with vanilla JS. As mentioned in the Vue section, it took a little bit longer to set up an event listener to handle whenever the enter button was pressed. This essentially required an onKeyPress event to be handled by the input tag, as such:

在这里超级简单,几乎就像我们将如何使用香草JS处理onClick 。 如Vue部分所述,每当按下Enter键时,设置事件侦听器进行处理就花费了更长的时间。 本质上,这需要由输入标签处理onKeyPress事件,例如:

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

This function essentially triggered the createNewToDoItem function whenever it recognised that the ‘enter’ key had been pressed, as such:

只要该函数识别出已按下“ enter”键,便会触发createNewToDoItem函数,例如:

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

In Vue it is super straight-forward. We simply use the @ symbol, and then the type of event-listener we want to do. So for example, to add a click event listener, we could write the following:

在Vue中,它非常简单明了。 我们只使用@符号,然后使用我们想要做的事件监听器的类型。 因此,例如,要添加一个click事件监听器,我们可以编写以下代码:

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

Note: @click is actually shorthand for writing v-on:click. The cool thing with Vue event listeners is that there are also a bunch of things that you can chain on to them, such as .once, which prevents the event listener from being triggered more than once. There are also a bunch of shortcuts when it comes to writing specific event listeners for handling key strokes.

注意: @click实际上是编写v-on:click简写。 Vue事件侦听器很酷的事情是,您还可以将许多东西链接到它们,例如.once ,这可以防止事件侦听器被多次触发。 在编写用于处理按键的特定事件侦听器时,还有许多捷径。

I found that it took quite a bit longer to create an event listener in React to create new ToDo items whenever the enter button was pressed. In Vue, I was able to simply write:

我发现,每当按下回车按钮时,在React中创建一个事件侦听器以创建新的ToDo项就花费了很多时间。 在Vue中,我能够简单地编写:

<input type=”text” v-on:keyup.enter=”createNewToDoItem”/>
我们如何将数据传递给子组件? (How do we pass data through to a child component?)
React: (React:)

In React, we pass props onto the child component at the point where it is created. Such as:

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

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

Here we see two props passed to the ToDoItem component. From this point on, we can now reference them in the child component via this.props. So to access the item.todo prop, we simply call this.props.item.

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

Vue: (Vue:)

In Vue, we pass props onto the child component at the point where it is created. Such as:

在Vue中,我们将道具传递到子组件的创建位置。 如:

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

Once this is done, we then pass them into the props array in the child component, as such: props: [ ‘todo’ ]. These can then be referenced in the child by their name — so in our case, ‘todo.

完成此操作后,我们将它们传递到子组件的props数组中,如下所示: props: [ 'todo' ] 。 然后可以在孩子的名字中引用它们的名称,因此在我们的情况下为'todo '

我们如何将数据发回到父组件? (How do we emit data back to a parent component?)

React: (React:)

We firstly pass the function down to the child component by referencing it as a prop in the place where we call the child component. We then add the call to function on the child by whatever means, such as an onClick, by referencing this.props.whateverTheFunctionIsCalled. This will then trigger the function that sits in the parent component.

首先,通过在调用子组件的地方将其作为道具引用,将函数传递给子组件。 然后,通过引用this.props.whateverTheFunctionIsCalled ,可以通过任何方式(例如onClick在子this.props.whateverTheFunctionIsCalled上添加对函数的调用。 然后,这将触发位于父组件中的函数。

We can see an example of this entire process in the section ‘How do we delete from the list’.

我们可以在“如何从列表中删除 ”部分中看到整个过程的示例

Vue: (Vue:)

In our child component, we simply write a function that emits a value back to the parent function. In our parent component, we write a function that listens for when that value is emitted, which can then trigger a function call. We can see an example of this entire process in the section ‘How do we delete from the list’.

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

我们终于得到它了! ? (And there we have it! ?)

We’ve looked at how we add, remove and change data, pass data in the form of props from parent to child, and send data from the child to the parent in the form of event listeners.

我们已经研究了如何添加,删除和更改数据,如何以props形式将数据从父级传递到子级,以及如何以事件侦听器的形式将数据从子级发送到父级。

There are, of course, lots of other little differences and quirks between React and Vue, but hopefully the contents of this article has helped to serve as a bit of a foundation for understanding how both frameworks handle stuff ?

当然,React和Vue之间还有许多其他的小差异和怪异之处,但是希望本文的内容可以为理解这两个框架如何处理东西奠定基础。

If you found this useful, please share on social media and comment!

如果您发现此功能有用,请在社交媒体上分享并发表评论!

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

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

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

React待办事项: https : //github.com/sunil-sandhu/react-todo

This is a syndicated repost for freeCodeCamp in collaboration with Javascript In Plain English. The original version of this article can be found here.

这是freeCodeCamp与Javascript in Plain English联合发布的联合发布。 可以在这里找到本文的原始版本。

翻译自: https://www.freecodecamp.org/news/i-created-the-same-app-in-react-and-vue-here-are-the-differences-67e71421df31/

vue和react相同点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值