After using Vue in my work, I already know a lot about it. At the same time, I was also curious about React. I read the React documentation and watched some tutorial videos, and while they were great, what I really wanted to know was how React differed from Vue. The difference here is not about whether they all have a virtual DOM or how they render the page. What I really wanted to do was do a side-by-side comparison of their code and figure out what the differences were when developing applications using the two frameworks.

I decided to build a standard to-do application where users could add and remove to-do items. I created the application using their default CLI (create-react-app for React and vue-CLI for Vue) respectively. Let’s take a look at what the two apps look like:

The CSS code in the two applications is almost identical, but the locations of the code are different.

The structure is almost identical, with the only difference being that React has three CSS files while Vue doesn’t. This is because the React component requires an attached file to store styles, whereas Vue uses containment to declare styles in component files.

In theory, you could use the old-fashioned style.css file to save the style of the entire page. It’s up to you. Anyway, here’s what the CSS code in the.vue file looks like:

Having looked at the styling issues, now let’s dive into the other details!

When we say “mutate data,” we actually mean to modify data that has already been saved. For example, if we want to change a person’s name from John to Mark, we “change the data.” This is one of the key differences between React and Vue. Vue creates a data object, which we can update freely, whereas React creates a state object, which requires more work to update. Here’s how React’s state objects compare to Vue’s data objects:

React state object:

Vue data objects:

As you can see, we’re passing in the same data; they’re just labeled differently. But there are big differences in how they change that data.

Suppose we have a data element name:’Sunil’.

In Vue, we refer to it by this.name. We can also update it with this.name=’John’, which will change the name to John.

In React, we refer to it by this.state.name. The key difference is that we can’t simply update it with this.state.name=’John’ because React restricts this. In React, we need to update the data using this.setstate ({name:’John’}).

Now that you’ve seen how to modify the data, let’s dive into other details by looking at how to add new items to your to-do application.

React:

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

Vue:

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

In React, input has a property called value. We update the value automatically through several functions related to creating a bidirectional binding. React handles bidirectional binding by attaching the onChange function to the input.

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

Whenever the value of input changes, the handleInput function is executed. This function changes the value of the toDO field in the state object to the value in the input. The function looks like this:

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

Now, whenever the user presses the + button on the page, createNewToDoItem calls this.setState and passes in a function. This function takes two arguments, the first a list array of state objects, and the second a todo (updated by the handleInput function). The function then returns a new object that contains the entire previous list and adds todo to the end of the list.

Finally, we set todo to an empty string, which also automatically updates the values in the input.

In Vue, input has an attribute called V-model. We can use it for bidirectional binding.

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

The V-Model binds the input to a key of the data object toDoItem. When loading the page, we set toDoItem to an empty string, such as todo: ‘. If todo is not empty, such as todo: ‘add some text here’, then the input will display this string. Any text we enter in the input will be bound to Todo. This is essentially two-way binding (input can update data objects, and data objects can update input).

So, looking back at the previous createNewToDoItem() block, we put the contents of todo into the List array, and then updated todo to an empty string.

React:

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

Although the deleteItem function is in todo.js, I can still reference it in todoitem.js by passing the deleteItem() function as a prop:

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

This allows the child component to access the function passed in. We also bind this to the key argument, which the function passing in needs to determine which ToDoItem to remove. Inside the ToDoItem component, we do the following:

< div className = "ToDoItem - Delete" onClick = {this. Props. Called deleteItem} > - < / div >Copy the code

I use this.props. DeleteItem to reference functions in the parent component.

Vue:

$on(' delete ', (event) => {this.list = this.list. Filter (item => item.todo! == event) })Copy the code

Vue has a slightly different approach, and we basically do three things.

First, we need to call the function on the element:

< div class = "ToDoItem - Delete" @ click = "called deleteItem (todo)" > - < / div >Copy the code

We then have to create an EMIT function as a method inside the child component (in this case todoitem.vue), as follows:

DeleteItem (todo) {this.$parent.$emit(' delete ', todo)}Copy the code

Then our parent function, this.$on(‘ delete ‘) event listener will fire the filter function when it is called.

To put it simply, a child component in React can access the parent function through this.props, whereas in Vue, events must be sent from the child component to the parent, which then needs to listen for those events and execute the function when it is called.

It is worth noting here that, in the Vue example, I could also write the $emit part directly into the @click listener, as follows:

< div class = "ToDoItem - Delete" @ click = "enclosing $parent. $emit (" Delete", todo) "> - < / div >Copy the code

This saves some code, but it depends on personal preference.

React:

Event listeners for simple events, such as click events, are simple. Here is an example of how we create a click event for a button that adds a new to-do:

The < div className = "ToDo - Add" onClick = {this. CreateNewToDoItem} > + < / div >Copy the code

Very simple, it looks a lot like using pure JS to handle inline onClick events. In Vue, it takes longer to set up event listeners. The input tag needs to handle the onKeyPress event as follows:

< input type = "text" onKeyPress = {this. HandleKeyPress} / >Copy the code

This function fires the createNewToDoItem function as soon as the user presses the ‘Enter’ key, as shown below:

HandleKeyPress = (e) => {if (e.key === 'Enter') {this.createnewTodoItem (); }};Copy the code

Vue:

In Vue, this is very simple to implement. We just need to use the @ symbol and the type of the event listener. For example, to add a click event listener, we could write:

< div class = "ToDo - Add @ click" = "createNewToDoItem ()" > + < / div >Copy the code

Note: @click is actually short for V-on :click. In Vue, we can link a lot of things to event listeners, for example.once prevents event listeners from being fired more than once. There are also shortcuts you can use when writing listeners to handle keyword-specific events. I found that creating an event listener for adding to-do buttons in React took a little longer. In Vue, I could simply write:

< input type = "text" v - on: keyup. Enter createNewToDoItem = "" / >Copy the code

React:

In React, when we create a child component, we pass props to it.

<ToDoItem key={key} item={todo} />Copy the code

We passed todo props to the ToDoItem component. From now on, we can reference them in child components via this.props. So, to access item.todo, we simply call this.props. Todo.

Vue:

In Vue, when we create a child component, we pass props to it.

<ToDoItem v-for="item in this.list"
          :todo="item.todo"
          :key="list.indexOf(item)"
          :id="list.indexOf(item)"
>
</ToDoItem>Copy the code

We then add them to the props array of the subcomponents, such as: props:[‘ ID ‘,’todo’]. You can then refer to them by name in child components, entering ‘id’ and ‘todo’.

React:

We pass the function as prop to the child component when we call it, and then call the child’s function in any way that triggers the function located in the parent component. We can see an example of this process in the section “How to Delete a To-do list.”

Vue:

In our child component, we simply write a function that sends a value back to the parent function. In the parent component, we write a function to listen for this value and then trigger the function call. We can see an example of this process in the section “How to Delete a To-do list.”

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

React: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-e9 a1ae8077fd