Comparação de React e Vue em um exemplo prático

O autor do material, cuja tradução publicamos hoje, diz que precisa usar o Vue no trabalho e que estudou bem essa estrutura. No entanto, ele estava sempre curioso para descobrir como as coisas estão em outros mundos, a saber, no universo React.

Ele leu a documentação, assistiu a alguns vídeos de treinamento e, embora tudo isso lhe parecesse muito útil, ele queria realmente entender qual era a diferença entre React e Vue. Para ele, a busca por diferenças entre os frameworks não era descobrir se eles suportam o modelo de objeto virtual do documento ou como exatamente eles renderizam as páginas. Ele queria que alguém lhe explicasse as características do código, para mostrar o que estava acontecendo nele. Ele esperava encontrar um artigo dedicado a descobrir exatamente essas diferenças, depois de ler que alguém que conhecia apenas Vue ou React (ou uma pessoa completamente nova no desenvolvimento da Web) podia entender melhor as diferenças entre essas estruturas.



No entanto, ele não conseguiu encontrar esse artigo. Esse fato o levou a entender que ele próprio tinha que pegar esse artigo e escrever ao longo do caminho, entendendo as semelhanças e diferenças entre React e Vue. De fato, aqui está uma descrição de seu experimento em comparação com essas duas estruturas.

Disposições Gerais



Vue ou reagir?

Para o experimento, decidi criar alguns aplicativos de tarefas bastante padrão, que permitem ao usuário adicionar itens à lista de tarefas e removê-los. Ambos os aplicativos são desenvolvidos usando create-react-app padrão ( create-react-app para React e vue-cli para Vue). A CLI é, se alguém não souber, uma abreviação que significa Command Line Interface, ou seja, uma interface de linha de comando.

Agora, proponho olhar para a aparência dos aplicativos em questão aqui.


Aplicativos criados por Vue e React

Aqui estão os repositórios com o código para esses aplicativos: Vue ToDo , React ToDo .

O mesmo código CSS é usado lá e ali, a única diferença é onde exatamente os arquivos correspondentes estão localizados. Diante disso, vamos dar uma olhada na estrutura dos projetos.


Estrutura do projeto usando Vue e reagir

Como você pode ver, a estrutura desses dois projetos é quase idêntica. A única grande diferença é que o aplicativo React possui três arquivos CSS, enquanto o aplicativo Vue não os possui. O motivo disso é que, ao usar o create-react-app , os componentes do React são equipados com os arquivos CSS que o acompanham e o Vue CLI adota uma abordagem diferente quando os estilos são declarados dentro de um arquivo de componente específico.

Como resultado, tanto a abordagem como a outra nos permitem alcançar o mesmo objetivo, enquanto, se desejado, nada nos impede de organizar estilos de maneira diferente do Vue ou React. De fato, tudo se resume às preferências pessoais da pessoa que cria o projeto da web. Por exemplo, o tópico de estruturação de CSS está sendo constantemente discutido nas comunidades de desenvolvedores. Agora, apenas seguimos as abordagens CSS padrão estabelecidas na CLI dos frameworks em questão.

No entanto, antes de prosseguirmos, vejamos como é um componente típico do Vue e do React.

Aqui está o código do componente Vue (em nosso projeto, ele está no arquivo ToDoItem.vue ).

 <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> 

Aqui está o código para o componente React (arquivo ToDoItem.js ).

 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; 

Agora é hora de mergulhar nos detalhes.

Como é feita a modificação de dados?


Alterar dados também é chamado de "mutação de dados". Estamos falando de alterações feitas nos dados que nosso aplicativo armazena. Portanto, se precisarmos alterar o nome de uma determinada pessoa de "John" para "Mark", estaremos falando sobre "mutação de dados". É na abordagem da mudança de dados que reside a principal diferença entre React e Vue. Ou seja, o Vue cria um objeto de data no qual os dados estão localizados e seu conteúdo pode ser alterado livremente. React cria um objeto de state no qual o estado do aplicativo é armazenado e, ao trabalhar com ele, é necessário algum esforço adicional para alterar os dados. No entanto, no React, tudo é organizado dessa maneira por um motivo, falaremos sobre isso abaixo e, para começar, consideraremos os objetos mencionados acima.

É assim que o objeto de data usado pelo Vue se parece.

 data() {     return {         list: [             {               todo: 'clean the house'             },             {               todo: 'buy milk'             }         ],     } }, 

Veja como é o objeto de state usado no React:

 constructor(props) {       super(props);       this.state = {           list: [               {                   'todo': 'clean the house'               },               {                   'todo': 'buy milk'               }           ],       };   }; 

Como você pode ver, nos dois casos, descrevemos os mesmos dados, eles são projetados de maneira diferente. Como resultado, podemos dizer que a transferência dos dados iniciais para os componentes no Vue e no React é muito, muito semelhante. Mas, como já mencionado, as abordagens para alterar os dados existentes nessas estruturas diferem.

Suponha que tenhamos um elemento de dados como o name: 'Sunil' . Em seguida, atribuí à propriedade name meu próprio nome.

No Vue, você pode acessar esses dados usando a construção this.name . E aqui está como alterá-los: this.name = 'John' . Não sei exatamente como me sentiria se meu nome realmente mudasse, mas no Vue funciona assim.

No React, você pode acessar os mesmos dados usando a construção this.state.name . Mas alterá-los escrevendo algo como this.state.name = 'John' não é possível, pois o React possui restrições que impedem essas alterações de dados. Portanto, no React, você deve usar algo como this.setState({name: 'John'}) .

O resultado dessa operação é o mesmo que o obtido após a execução de uma operação mais simples no Vue. Você precisa escrever mais código no React, mas no Vue há algo como uma versão especial da função setState , chamada quando, ao que parece, uma simples alteração de dados. Portanto, para resumir, o React requer o uso do setState com a descrição dos dados que precisam ser alterados, e o Vue trabalha no pressuposto de que o desenvolvedor gostaria de usar algo semelhante alterando os dados dentro do objeto de data .

Agora vamos nos perguntar por que o React foi setState e por que a função setState é necessária. Você pode encontrar respostas para estas perguntas em Revant Kumar : “Isso ocorre porque o React procura reexecutar, mediante uma alteração de estado, certos ganchos do ciclo de vida, como componentWillReceiveProps , shouldComponentUpdate , componentWillUpdate , render , componentDidUpdate . Ele descobre que o estado mudou quando você chama a função setState . Se você alterasse o estado diretamente, o React precisaria fazer muito mais trabalho para rastrear alterações, determinar quais ganchos do ciclo de vida executar e assim por diante. Como resultado, o React usa o setState para facilitar a vida. ”

Agora que descobrimos as alterações nos dados, vamos falar sobre como, em ambas as versões do nosso aplicativo, adicionar novos itens à lista de tarefas.

Adicionar novos itens à lista de tarefas


EaReativar


Veja como fazer isso no React.

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

Aqui, o campo usado para input dados ( input ), tem o value do atributo. Esse atributo é atualizado automaticamente através do uso de um par de funções interconectadas que formam o que é chamado de ligação de dados bidirecional (se você nunca ouviu falar disso antes - espere um pouco, falaremos sobre isso na seção sobre como adicionar elementos ao aplicativo Vue). Criamos esse tipo de comunicação bidirecional devido à presença de um onChange evento onChange adicional anexado ao campo de input . Vamos dar uma olhada no código desse campo para que você possa entender o que está acontecendo aqui.

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

A função handleInput chamada quando o valor do campo de input alterado. Isso leva à atualização do elemento todo , que está dentro do objeto state , configurando-o para o valor que está no campo de input . É assim que a função handleInput parece.

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

Agora, quando o usuário clica no botão + na página do aplicativo para adicionar um novo registro à lista, a função createNewToDoItem chama o método this.setState e passa a função. Esta função usa dois parâmetros. O primeiro é a matriz de list inteira do objeto state e o segundo é o elemento todo atualizado pela função handleInput . A função então retorna um novo objeto que contém a matriz de list antiga e adiciona um novo elemento todo ao final dessa matriz. O trabalho com a lista é organizado usando o operador de spread (se você nunca o conheceu antes, saiba que esse é um dos novos recursos do ES6 e procure detalhes sobre ele).

Por fim, uma string vazia é gravada em todo , que atualiza automaticamente o value no campo de input .

▍Vue


A construção a seguir é usada para adicionar um novo item à lista de tarefas no Vue.

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

No Vue, o campo de entrada possui uma diretiva de v-model . Permite organizar a ligação de dados bidirecional. Dê uma olhada no código desse campo e fale sobre o que está acontecendo aqui.

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

A diretiva v-model vincula um campo a uma chave que existe em um objeto de dados chamado toDoItem . Quando a página é carregada, uma linha vazia é escrita em toDoItem , ela se parece com todo: '' .

Se já houver alguns dados, algo como todo: 'add some text here' , o mesmo texto entrará no campo de entrada, ou seja - 'add some text here' . De qualquer forma, se retornarmos ao exemplo com uma sequência vazia, o texto que inserirmos no campo cairá, devido à ligação de dados, na propriedade todo . Essa é uma ligação de dados bidirecional, ou seja, a inserção de novos dados no campo leva ao registro desses dados no objeto de data e a atualização dos dados no objeto leva à aparência desses dados no campo.

Agora lembre-se da função createNewToDoItem() , sobre a qual falamos acima. Como você pode ver, colocamos o conteúdo de todo na matriz da list e, em seguida, escrevemos uma string vazia em todo .

Removendo itens de uma lista


EaReativar


Em React, esta operação é executada assim.

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

Enquanto a função deleteItem estiver no arquivo ToDo.js , você poderá acessá-la sem problemas no ToDoItem.js , passando essa função como uma propriedade para <ToDoItem/> . Aqui está o que parece:

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

Aqui passamos primeiro a função, que a torna disponível para componentes filhos. Além disso, ligamos this e passamos o parâmetro key . Este parâmetro é usado pela função para distinguir o elemento ToDoItem a ser excluído de outros elementos. Em seguida, dentro do componente ToDoItem , fazemos o seguinte.

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

Tudo o que precisa ser feito para acessar a função localizada no componente pai é usar a construção this.props.deleteItem .

▍Vue


A exclusão de um item da lista no Vue é feita assim.

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

O Vue requer uma abordagem ligeiramente diferente para remover elementos do que usamos no React. Ou seja, há três etapas a serem tomadas.

Primeiro, aqui está o que você precisa fazer no elemento para o qual você precisa chamar a função para excluí-la.

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

Em seguida, você precisa criar a função de emit como um método no componente filho (neste caso, em ToDoItem.vue ), que se parece com isso.

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

Além disso, você pode perceber que estamos adicionando ToDoItem.vue dentro do ToDo.vue .

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

Isso é chamado de ouvinte de eventos personalizado. Ele responde para emit chamadas com a linha de delete . Se ele captura um evento semelhante, chama a função onDeleteItem . Ele está localizado dentro do ToDo.vue e não no ToDoItem.vue . Essa função, como mencionado acima, simplesmente filtra a matriz de todo localizada no objeto de data para remover o elemento que foi clicado nela.

Além disso, vale ressaltar que no exemplo usando o Vue, pode-se simplesmente escrever o código relacionado à função de emit dentro do @click . Pode ser assim.

 <div class="ToDoItem-Delete" @click="$emit('delete', todo)">-</div> 

Isso reduziria o número de etapas necessárias para remover um item da lista de três para dois. Como proceder é uma questão de preferência do desenvolvedor.

Para resumir esta seção, podemos dizer que no React, o acesso às funções descritas nos componentes pai é organizado por meio deste this.props (dado que os props passados ​​aos componentes filhos, que é uma técnica padrão que pode ser encontrada literalmente em qualquer lugar). No Vue, os componentes filhos devem acionar eventos usando a função de emit , e esses eventos já são tratados pelo componente pai.

Trabalhar com ouvintes de eventos


EaReativar


No React, os ouvintes de eventos para algo simples, como um evento de clique, são bastante simples. Aqui está um exemplo de criação de um manipulador de eventos de click para um botão que cria um novo item de tarefa.

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

Tudo é organizado de maneira simples aqui, é muito semelhante ao processamento desses eventos usando JavaScript puro.

Deve-se observar que aqui, configurar ouvintes de eventos para pressionar as teclas, por exemplo, para Enter , leva um pouco mais do que no Vue. Aqui você precisa que o evento onKeyPress tratado da seguinte maneira. Aqui está o código para o campo de entrada.

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

A função handleKeyPress chama a função createNewToDoItem quando reconhece uma handleKeyPress em Enter . Parece assim.

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

▍Vue


Os manipuladores de eventos no Vue são muito fáceis de configurar. Basta usar o símbolo @ e especificar o tipo de ouvinte que queremos usar.

Por exemplo, para adicionar um ouvinte de evento de clique, você pode usar o seguinte código.

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

Observe que @click é a abreviação de v-on:click . Os ouvintes de eventos do Vue são bons em serem muito bem controlados. Por exemplo, anexar a construção .once ao ouvinte fará com que o ouvinte seja .once apenas uma vez.

Existem muitas abreviações que simplificam a escrita dos ouvintes que respondem às teclas digitadas no teclado. No React, como dissemos, isso leva mais tempo do que no Vue. Aqui é feito de maneira muito simples.

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

Passando dados para componentes filho


EaReativar


Em React, as propriedades são passadas para o componente filho quando ele é criado. Por exemplo, assim:

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

Aqui você pode ver duas propriedades passadas para o componente ToDoItem . A partir de agora, eles podem ser acessados ​​no componente filho via this.props .

Por exemplo, para acessar a propriedade item.todo , basta usar a construção this.props.item .

▍Vue


No Vue, as propriedades também são passadas para os componentes filhos quando eles são criados.

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

Depois disso, eles são passados ​​para a matriz props do componente filho, por exemplo, usando a construção props: [ 'todo' ] . Você pode acessar essas propriedades nos componentes filhos pelo nome; no nosso caso, é o nome 'todo' .

Passando dados para o componente pai


EaReativar


No React, a função é passada primeiro ao componente filho como uma propriedade na qual o componente filho é chamado. Em seguida, está planejado chamar essa função, por exemplo, adicionando-a como manipulador onClick ou chamando-a chamando this.props.whateverTheFunctionIsCalled . Isso leva a uma chamada para a função localizada no componente pai. Este processo é descrito na seção sobre remoção de itens da lista.

▍Vue


Ao usar o Vue, em um componente filho, basta escrever uma função que transmita dados para a função pai. Uma função é gravada no componente pai que escuta eventos de transferência de valor. Quando um evento semelhante ocorre, essa função é chamada. Assim como o React, uma descrição desse processo pode ser encontrada na seção sobre remoção de itens da lista.

Sumário


Falamos sobre como adicionar, remover e modificar dados em aplicativos baseados no Vue e React, como transferir dados, na forma de propriedades, de componentes pai para filhos e como enviar dados de componentes filhos para pais. Acreditamos que, depois de analisar os exemplos de semelhanças e diferenças, Vue e React são visíveis, como se costuma dizer, a olho nu.

Obviamente, existem muitas outras pequenas diferenças entre o React e o Vue, mas espero que o que abordamos aqui sirva como uma boa base para entender como essas estruturas funcionam. As estruturas são frequentemente analisadas ao escolher a plataforma certa para um novo projeto. Esperamos que este material ajude a fazer essa escolha.

Caros leitores! Que diferenças entre React e Vue, na sua opinião, são as mais importantes que afetam a escolha de uma estrutura específica, por exemplo, como base para um determinado projeto?

Source: https://habr.com/ru/post/pt419373/


All Articles