create-react-app
for React and vue-cli
for Vue). The CLI is, if anyone does not know, the abbreviation, which is decoded as the Command Line Interface, that is, the command line interface.create-react-app
, React components are equipped with accompanying CSS files, and CLI Vue uses a different approach when styles are declared within a particular component file.ToDoItem.vue
file). <template> <div class="ToDoItem"> <p class="ToDoItem-Text">{{todo.text}}</p> <div class="ToDoItem-Delete" @click="deleteItem(todo)">- </div> </div> </template> <script> export default { name: "to-do-item", props: ['todo'], methods: { deleteItem(todo) { this.$emit('delete', todo) } } } </script> <style> .ToDoItem { display: flex; justify-content: center; align-items: center; } .ToDoItem-Text { width: 90%; background-color: white; border: 1px solid lightgrey; box-shadow: 1px 1px 1px lightgrey; padding: 12px; margin-right: 10px; } .ToDoItem-Delete { width: 20px; padding: 5px; height: 20px; cursor: pointer; background: #ff7373; border-radius: 10px; box-shadow: 1px 1px 1px #c70202; color: white; font-size: 18px; margin-right: 5px; } .ToDoItem-Delete:hover { box-shadow: none; margin-top: 1px; margin-left: 1px; } </style>
ToDoItem.js
file). import React, {Component} from 'react'; import './ToDoItem.css'; class ToDoItem extends Component { render() { return ( <div className="ToDoItem"> <p className="ToDoItem-Text">{this.props.item}</p> <div className="ToDoItem-Delete" onClick={this.props.deleteItem}>-</div> </div> ); } } export default ToDoItem;
data
object in which the data is located, and the contents of which can be freely changed. React creates a state
object that stores the state of the application, and when working with it, some additional effort is required to change the data. However, in React everything is arranged that way, not without reason, below we will talk about it, but first we will consider the above-mentioned objects.data
object used in Vue looks like. data() { return { list: [ { todo: 'clean the house' }, { todo: 'buy milk' } ], } },
state
object used in React looks like: constructor(props) { super(props); this.state = { list: [ { 'todo': 'clean the house' }, { 'todo': 'buy milk' } ], }; };
name: 'Sunil'
. Here I assigned my own name to the name
property.this.name
. And here is how to change them: this.name = 'John'
. I don’t know exactly how I would feel if my name really changed, but in Vue it works that way.this.state.name
. But you cannot change them by writing something like this.state.name = 'John'
, since there are restrictions in React that prevent such changes in data. Therefore, in React you have to use something like this.setState({name: 'John'})
.setState
function, which is called when, as it seems, a simple data change. Therefore, to sum up, React requires the use of the setState
with passing description of the data to be changed, and Vue works on the assumption that the developer would like to use something like this by changing the data inside the data
object.setState
function is needed at all. You can find answers to these questions from Revanta Kumar : “This is so because React seeks to re-execute, as the state changes, certain life-cycle hooks, such as componentWillReceiveProps
, shouldComponentUpdate
, componentWillUpdate
, render
, componentDidUpdate
. It learns that the state has changed when you call the setState
function. If you were changing the state directly, React would have to do much more work to track changes, to determine which life cycle hooks need to be run, and so on. As a result, React uses setState
to make life easier for itself. ” createNewToDoItem = () => { this.setState( ({ list, todo }) => ({ list: [ ...list, { todo } ], todo: '' }) ); };
input
field ( input
) has a value
attribute. This attribute is updated automatically through the use of a pair of interrelated functions that form what is called two-way data binding (if you have not heard of this before - wait a bit, we'll talk about this in the section on adding elements in a Vue application). We create this kind of two-way communication due to the presence of an additional onChange
event onChange
attached to the input
field. Take a look at the code of this field so that you can understand what is happening here. <input type="text" value={this.state.todo} onChange={this.handleInput}/>
handleInput
function handleInput
called when the value of the input
field changes. This leads to updating the todo
element, which is inside the state
object, by setting it to the value that is in the input
field. Here is the handleInput
function. handleInput = e => { this.setState({ todo: e.target.value }); };
+
button on the application page to add a new record to the list, the createNewToDoItem
function calls the method this.setState
and passes the function to it. This function takes two parameters. The first is the entire list
array from the state
object, and the second is the todo
element, updated by the handleInput
function. The function then returns a new object that contains the old list
array, and adds a new todo
element to the end of this array. Working with the list is organized using the spread
operator (if you have not met with it before - know that this is one of the new features of ES6, and look for details about it).todo
, which automatically updates the value of value
in the input
field. createNewToDoItem() { this.list.push( { 'todo': this.todo } ); this.todo = ''; }
v-model
directive. It allows you to organize two-way data binding. Take a look at the code of this field and talk about what is happening here. <input type="text" v-model="todo"/>
v-model
directive binds the field to a key that is in the data object called toDoItem
. When the page loads, an empty line is written to toDoItem
, it looks like todo: ''
.todo: 'add some text here'
, then the same text will appear in the input field, that is, 'add some text here'
. In any case, if you go back to the example with an empty line, the text that we enter in the field will be, due to the data binding, in the todo
property. This is a two-way data binding, that is, entering new data into the field results in writing this data into the data
object, and updating the data in the object results in the appearance of this data in the field.createNewToDoItem()
function, which we talked about above. As you can see, we put the contents of todo
in the list
array, and then write an empty string in todo
. deleteItem = indexToDelete => { this.setState(({ list }) => ({ list: list.filter((toDo, index) => index !== indexToDelete) })); };
deleteItem
function is in the ToDo.js
file, you can easily access it from ToDoItem.js
by first passing this function as a property to <ToDoItem/>
. Here's what it looks like: <ToDoItem deleteItem={this.deleteItem.bind(this, key)}/>
this
and pass the key
parameter. This parameter is used by the function to distinguish the ToDoItem
element to be removed from other items. Then, inside the ToDoItem
component, we do the following. <div className="ToDoItem-Delete" onClick={this.props.deleteItem}>-</div>
this.props.deleteItem
. onDeleteItem(todo){ this.list = this.list.filter(item => item !== todo); }
<div class="ToDoItem-Delete" @click="deleteItem(todo)">-</div>
emit
function as a method in the child component (in this case, in ToDoItem.vue
), which looks like this. deleteItem(todo) { this.$emit('delete', todo) }
ToDoItem.vue
inside ToDo.vue
, access the function. <ToDoItem v-for="todo in list" :todo="todo" @delete="onDeleteItem" // <-- this :) :key="todo.id" />
emit
calls with the string delete
. If it captures a similar event, it calls the onDeleteItem
function. It is inside ToDo.vue
, and not in ToDoItem.vue
. This function, as mentioned above, simply filters the todo
array located in the data
object in order to remove the element it clicked from.emit
function inside the @click
. It may look like this. <div class="ToDoItem-Delete" @click="$emit('delete', todo)">-</div>
this.props
(taking into account that props
passed to child components, which is a standard technique that can be found literally everywhere). In Vue, the child components must trigger events using the emit
function, and these events are already handled by the parent component.click
event handler for a button that creates a new to-do item. <div className="ToDo-Add" onClick={this.createNewToDoItem}>+</div>
Enter
, takes a little longer than in Vue. Here it is necessary that the onKeyPress
event onKeyPress
handled as follows. Here is the code for the input field. <input type="text" onKeyPress={this.handleKeyPress}/>
handleKeyPress
function calls the createNewToDoItem
function when it recognizes pressing Enter
. It looks like this. handleKeyPress = (e) => { if (e.key === 'Enter') { this.createNewToDoItem(); } };
@
symbol, and then specify the type of listener that we want to use. <div class="ToDo-Add" @click="createNewToDoItem()">+</div>
@click
is short for v-on:click
. Vue event listeners are good in that they can be managed very finely. For example, if you attach a .once
construct to a .once
, this will cause the listener to work only once. <input type="text" v-on:keyup.enter="createNewToDoItem"/>
<ToDoItem key={key} item={todo} />
ToDoItem
component. From this point on, they can be accessed in the child component via this.props
.item.todo
property, it suffices to use the construction of this.props.item
. <ToDoItem v-for="todo in list" :todo="todo" :key="todo.id" @delete="onDeleteItem" />
props
array of the child component, for example, using the props: [ 'todo' ]
construct. You can refer to these properties in child components by name, in our case this name is 'todo'
.onClick
handler, or by calling it by calling this.props.whateverTheFunctionIsCalled
. This leads to a function call that is in the parent component. This process is described in the section on removing items from the list.Source: https://habr.com/ru/post/419373/
All Articles