Semana Omnistack 10 — Frontend em VueJS
Comparando as implementações em React e VueJS
O que foi a Semana Omnistack
Há algumas semanas eu participei da Semana Omnistack da Rocketseat, que propõe o desafio de implementar toda a stack de uma aplicação web utilizando apenas uma linguagem, o JavaScript (daí o nome Omnistack). No desafio, a stack consiste de um backend sendo executado em um servidor Node, um frontend que roda no browser e uma app para Android.
No servidor Node, utilizando o framework express, foi implementada uma API REST. Essa API se conecta com a API pública do GitHub para trazer informações sobre um desenvolvedor e salvá-las em uma base de dados MongoDB.
O frontend, escrito utilizando React e CSS, é uma página com um formulário de cadastro que aceita um username do GitHub, uma lista de tecnologias separadas por vírgulas, a latitude e a longitude do desenvolvedor que quer se cadastrar na plataforma. Ao lado do formulário está a lista de desenvolvedores já cadastrados.
O aplicativo possui um mapa e um campo de pesquisa, ao inserir uma tecnologia no campo de pesquisa são mostrados no mapa apenas os desenvolvedores que cadastraram aquela tecnologia nos seus perfis.
O meu desafio pessoal
A Omnistack não é sobre o uso de frameworks e sim sobre o uso de uma linguagem. Então tomei como um desafio pessoal reimplementar a aplicação do frontend, aquela implementada em React, utilizando o framework VueJS. Por quê? Para comparar a experiência de desenvolvimento entre as duas ferramentas.
Se deu da seguinte forma: Utilizando as mesmas bibliotecas e o mesmo CSS eu “traduzi” a lógica da aplicação para VueJS.
A seguir escrevo um pouco mais sobre cada etapa de desenvolvimento.
O resultado final e o código da minha versão da aplicação estão no repositório abaixo:
Ferramentas de CLI
Existe pouca diferença entre o create-react-app
, a CLI do React e a vue-cli
, ambas ferramentas são fáceis de instalar e de usar, a única diferença relevante é que o create-react-app
vem com mais código boiler plate.
O produto inicial das duas ferramentas é uma aplicação já configurada com linter e com hot-reload.
O que há em comum?
Depois de criar o básico da aplicação utilizando o vue-cli
organizei a estrutura das pastas e criei os arquivos dos componentes, ainda vazios. Reaproveitei o arquivo api.js
no diretório services
. Finalizando a preparação, Apaguei os códigos de boiler plate.
A partir daqui as modificações foram guiadas pelas práticas do framework Vue.
Diferenças no template
Acredito que essa seja a diferença fundamental entre o React e o Vue: o que se costuma dizer é que React é HTML dentro do JavaScript, já o Vue é Javascript dentro do HTML. Veja porquê:
Esse é o código do template base em React:
Através da sintaxe JSX, é possível transformar os componentes React em tags HTML, como podemos ver nas tags <DevForm>
e <DevItem>
Já nesse exemplo trazemos a raiz da aplicação em Vue:
O layout da aplicação fica dentro da tag <template>
.
Já podemos perceber que em VueJS programamos o comportamento de um template enquanto que em React programamos o que será retornado em uma função.
Agora explorarei as diferenças na implementação do formulário.
Diferenças no DevForm
Colocarei apenas os trechos de código do componente DevForm
que mostram as diferenças que mais me chamaram a atenção. Começando pelos inputs e a tag form
.
Como class
é uma palavra reservada do JavaScript, em React o atributo class de um elemento HTML é trocado por className
, também vale notar o uso de camelCase nos atributos. Os eventos são ligados à funções declaradas no script. Por exemplo, a função handleSubmit
é ligada ao evento submit
através do atributo onSubmit
.
O que a função handleSubmit
faz é chamar a função onSubmit
que foi passada como uma prop do componente, como pode ser visto abaixo.
Essa forma de programar as funções evidencia a característica do React de ser “HTML no JavaScript”.
Quero enfatizar também a forma como o React gerencia os estados dos inputs de texto.
Em linhas gerais, utilizando a função useState
estamos ligando a função setGithubUsername
ao valor da variável githubUsername
. Para evoluir o estado da aplicação é necessário usa essa função e essa variável no input como é mostrado no exemplo a seguir:
Na minha opinião, isso torna o código bastante burocrático e chato de escrever, em compensação, enfatiza o uso do paradigma funcional o que dá mais segurança às modificações de valores de variáveis.
Algo que me chamou a atenção também foi a forma como acessamos as funcionalidades de geolocalização do Browser assim que a página carrega:
A função useEffect
do React executa a função passada como parâmetro quando acontece um evento na lista passada como segundo parâmetro, se for passada uma lista vazia ela executa quando o componente é montado.
Agora vamos explorar como isso é feito em VueJS. Novamente, mostrando o trecho equivalente da tag form
e do input que controla o valor do githubUsername
.
Diferente do React, o Vue é escrito em HTML, inclusive a estrutura básica de um componente Vue é formada de três tags HTML:
<template>// ...</template><script>// ...</script><style>// ...</style>
Bom, não exatamente HTML, mas utilizando a sintaxe do HTML.
A ligação do evento de submit com a função handleSubmit
é feita utilizando uma sintaxe especial do Vue: @submit.prevent=handleSubmit
onde o @
é um atalho para v-on:
, para mais detalhes consulte a documentação do VueJS. O modificador prevent
é equivalente a fazer um preventDefault()
no evento de submit.
A função handleSubmit
então é mapeada no objeto methods
do componente:
Outro ponto relevante de diferença entre o React e o VueJS é a API de um componente. Enquanto em React tudo é comunicado através de props, em Vue um componente recebe props e emite eventos. Nesse caso emitimos um evento submit
para o componente pai do DevForm
enviando os dados de cada campo e logo após, limpamos as variáveis github_username
e techs
.
Já podemos perceber, pelos últimos passos da função, outra diferença entre as ferramentas: no VueJS é possível alterar as variáveis do estado do componente diretamente, desde que elas tenham sido declaradas na função data()
como a seguir:
Lembrando que o que liga a variável github_username
ao input de texto é a propriedade v-model
aplicada no input, que é um atalho para fazer um two way data binding.
A inicialização das variáveis latitude
e longitude
é feita através dos gatilhos de ciclo de vida do VueJS, que são autoexplicativos:
Utilizar o ciclo de vida torna a execução dessa tarefa mais clara, na minha opinião.
Acredito que tenha descrito as principais mudanças do componente DevForm
. Vamos agora analisar as diferenças mais relevantes da implementação do componente DevItem
.
Diferenças no DevItem
O componente DevItem
é mais simples, já que ele é apenas de apresentação, ou seja, não possui lógica, condicionais ou laços sendo executados. Ele recebe como prop um objeto dev
e mostra as propriedades. Veja o código em React:
Agora o código em VueJS:
Tem pouca diferença entre os componentes, nesse caso. Só gostaria de ressaltar a sintaxe do Vue no binding das propriedades do objeto dev
utilizando o atalho :
.
Diferenças no Componente Raiz
Podemos agora voltar ao componente Raiz do projeto para mostrar uma das diferenças que mais me chamou a atenção, a iteração sob a lista de devs
para criar os componentes DevItem
.
Veja primeiro o código em React:
Aqui ele literalmente itera na lista devs
usando um map
e retorna um DevItem
em cada iteração.
Vamos comparar com o código em Vue:
Já em VueJS, utilizando a diretiva v-for
iteramos de forma mais transparente na lista devs
.
Essa diferença mostra que em VueJS estamos implementando o comportamento de um layout enquanto que em React estamos inserindo um layout no meio do código JavaScript.
Conclusão
Acredito que a experiência de programar em VueJS é mais agradável em termos gerais. A API dos componentes e a sintaxe são mais intuitivas. E organizar seus componentes em um único arquivo é mais conveniente.
É por essas e outras vantagens observadas que eu prefiro utilizar o VueJS como o framework para aplicações web em JavaScript.
Lembrando que esse artigo representa a minha opinião e as minhas experiências, se você discorda, quer comparar com outras ferramentas, ou quer dar sua opinião sinta-se bem vindo a opinar nos comentários ou me contactar diretamente no Twitter através do @oesron ou pelo e-mail esron.silva@sysvale.com