

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