Covil Do Dev

VueJs: guia completo

Guia completo de como instalar e utilizar o VueJs. Veja quais são e como aplicar os principais recursos com passo-a-passo e exemplos práticos.


Lindomar Rodrigues
Lindomar Rodrigues

Atualizado

VueJs é um framework progressivo e reativo de código aberto utilizado para desenvolvimento de interfaces e SPA's.

A primeira versão do VueJs foi lançada em fevereiro de 2014 por um ex-funcionário do Google chamado Evan You.

É um dos frameworks mais populares e utilizados atualmente, com cerca de 190k estrelas no GitHub. Tem como foco a camada de visão, e um dos princípios é simplificar o desenvolvimento web e poder ser incluído em projetos já existente sem grandes dificuldades.

A instalação é simples e um projeto pode ser iniciado com uma estrutura de pastas básicas já definidas sem muita dificuldade.

Principais funcionalidades

Algumas das funcionalidades importantes do VueJs são explicadas abaixo(ordem alfabética).

Animação/Transição

VueJs tem por padrão várias formas de aplicar transições aos elementos HTML quando estes são adicionados, removidos ou atualizados do DOM.

VueJs inclui um componente que precisa ser colocado como pai do elemento que irá receber o efeito de transição, e pode ser facilmente customizado para adicionar mais interatividade a interface.

Também existem várias animações criadas pela comunidade disponíveis para serem utilizadas em qualquer projeto.

Componente

Um componente(component) é um elemento que pode ser reaproveitado em várias partes do código, muito útil para evitar repetições desnecessárias. Pode ser apenas a parte visual, mas também pode conter uma regra de negócio que será replicada em vários contextos.

Dado computado

Um dado computado (Computed Properties) funciona como uma variável padrão, porém responde a qualquer alteração nos dados que impactar em seu valor.

Na prática, é bem útil e evita utilizar a diretiva v-on em muitos casos, deixando a interface do usuário ainda mais fluída.

Diretiva

Diretivas ou Directives no VueJs são semelhantes ao visto em outras linguagens, alguns exemplos facilmente reconhecíveis são:

  • v-if
  • v-else-if
  • v-else
  • v-show
  • v-on
  • v-bind
  • v-model

São utilizadas no front-end da aplicação sendo responsáveis por boa parte das interações do usuário.

DOM Virtual

O DOM(Document Object Model) é a interface entre o JavaScript e os objetos visíveis do HTML.

O VueJs, assim como outros frameworks, como, por exemplo, Ember e React não fazem alterações diretamente no DOM, ao invés disso, uma réplica do DOM é criada e representada como uma estrutura de dados do JavaScript.

Quando alguma alteração na interface acontece, ela é efetuada inicialmente na estrutura de dados do JavaScript, e após isso comparada com o DOM original. Após isso, caso necessário a alteração é efetuada no DOM original e se torna visível ao usuário.

Utilizar o DOM virtual traz vários benefícios de desempenho, pois é menos custoso computacionalmente e oferece uma frequência de atualização superior comparado a atualizar a interface diretamente.

Escuta de eventos

Escuta de eventos, ou em inglês, event handling é o fato de esperar algum evento ser disparado para executar algum código com esse gatilho.

Em VueJs a diretiva v-on é utilizada para esse propósito.

interligação de dados

A interligação de dados, ou em inglês, data binding, é o fato de associar uma variável a um atributo HTML, bastando alterar essa variável e o conteúdo desse atributo será alterado como consequência.

Essa interligação pode ser realizada para o style, class ou praticamente qualquer outro atributo do HTML.

A diretiva responsável por essa funcionalidade no VueJs é o v-bind.

Leveza

Um script em VueJs costuma ser muito leve, o que geralmente garante uma alta desempenho.

Observador

Observadores (Watchers) são responsáveis por reagir à mudança de dados, por exemplo, em um formulário.

Utilizar um observador abstrai boa parte das tarefas necessárias para isso quando não se utiliza um framework.

Rotas

A navegação entre páginas também é abstraída no Vuejs com a ajuda de um componente chamado vue-router.

Template

Os templates do VueJs tem uma sintaxe baseada no HTML, porém com seus valores associados com o DOM virtual e a instância VueJs a qual é correspondente.

Os templates são compilados com as Render Functions do DOM virtual e podem ser substituídas pelo usuário com a própria render function.

Vue-CLI

A interface de linha de comando do VueJs trazem várias funcionalidades e abstrai vários processos, inclusive adição de componentes, a etapa de build e até a criação do projeto.

Comparações

No site oficial do VueJs estão presentes estas comparações, caso queira o original, em inglês está aqui, a versão traduzida(e um pouco desatualizada) está aqui.

Na documentação são comparados:

  • ReactJs vs VueJs
  • AngularJs vs VueJs
  • Angular vs VueJs
  • Ember vs VueJs
  • Knockout vs VueJs
  • Polymeter vs VueJs
  • Riot vs VueJs

Como adicionar VueJs ao projeto?

Existem várias formas de adicionar o VueJs ao seu projeto, veremos algumas logo abaixo.

No restante do artigo partiremos da criação utilizando a interface de linha de comando do VueJs (CLI), por facilitar já deixando pronto uma boa estrutura de pastas.

Tag script

Uma forma simples é baixando o VueJs e colocando o numa tag <script> como o caminho correto. Vue será registrado como uma variável global nesses casos.

Ao acessar o link de download você verá duas versões, uma de desenvolvimento e outra de produção.

A única diferença é que a versão de desenvolvimento irá exibir erros e conterá um modo debug, enquanto a versão de produção não contém isso e também não tem o código organizado visando a legibilidade e sim a economia de tamanho(33.46 KB).

<html>
<head>
    <script src="/rota/para/vue.js" type="text/javascript"></script>
</head>
<body></body>
</html>

CDN

VueJs também pode ser instalado com a ajuda de um CDN, ele está presente em vários, abaixo temos o exemplo da última versão utilizando o jsdelivr:

<html>
<head>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body></body>
</html>

Também está disponível no unpkg e no cdnjs.

<script src="https://unpkg.com/vue@2.6.14/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.14/vue.js"></script>

Em todos os exemplos esta sendo utilizado a versão de desenvolvimento, caso queira a versão de produção basta substituir /vue.js por /vue.min.js.

Também existe uma versão nativa ES, que é compatível com o build ES padrão.

<script type="module">
    import Vue from 'https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.esm.browser.js'
</script>

NPM

Esta é a forma de instalação recomendada para aplicações grandes feitas em VueJs. É compatível com Webpack e Browserify.

Para instalar basta utilizar o NPM como feito com qualquer outro módulo.

npm install vue

CLI

A interface de linha de comando do VueJs é bem prática e intuitiva de ser utilizada, para instalar basta utilizar o npm da seguinte forma.

npm install -g @vue/cli

Depois de alguns minutos a instalação será concluída, para iniciar um projeto basta utilizar o vue create, substituindo o <nome-do-projeto> pelo nome do projeto.

vue create <nome-do-projeto>

Estrutura de um projeto em VueJs

Se você criou o projeto utilizando o CLI do VueJs, terá algo semelhante ao mostrado abaixo.

.
├── babel.config.js
├── package.json
├── package-lock.json
├── public
│   ├── favicon.ico
│   └── index.html
├── README.md
└── src
    ├── App.vue
    ├── assets
    │   └── logo.png
    ├── components
    │   └── HelloWorld.vue
    └── main.js

Desenvolvendo uma aplicação em VueJs

Para utilizar as principais funcionalidades do VueJs que foram mostradas anteriormente, realizaremos uma aplicação simples, uma calculadora de IMC.

Porquê? Pois, com isso poderemos cobrir várias utilidades comuns no dia-a-dia, e inclusive algumas mais específicas que podem ser uteis em algum momento na sua jornada desenvolvendo em VueJs.

Para esse mini-projeto partiremos daquela estrutura básica mostrada anteriormente.

Rodando a aplicação

Inicialmente vamos rodar a aplicação em modo de desenvolvimento, na pasta raiz do projeto, basta executar o comando abaixo.

vue-cli-service serve

Se a parte da instalação e criação do projeto com o CLI foi feita corretamente, você deve conseguir abrir o link http://localhost:8080/ e ver algo semelhante ao mostrado na imagem abaixo.

Aplicação hello world VueJs

Preparando os arquivos

Simplificaremos um pouco substituindo o conteúdo do arquivo App.vue com a menor quantidade de código possível.

<template>
  <div>
  </div>
</template>

<script>

export default {
  name: 'App'
}
</script>

<style>
</style>

Podemos excluir os arquivos src/assets/logo.png e src/components/HelloWorld.vue, pois não os utilizaremos e dependendo da IDE e sua configuração pode ser que apareça algumas mensagens de erros. A estrutura do projeto ficará da seguinte forma.

.
├── babel.config.js
├── package.json
├── package-lock.json
├── public
│   ├── favicon.ico
│   └── index.html
├── README.md
└── src
    ├── App.vue
    ├── assets
    │   └── logo.png
    ├── components
    │   └── HelloWorld.vue
    └── main.js

Adicionando css

Para não atrasar muito o desenvolvimento podemos utilizar algum framework css, no exemplo utilizaremos C por ser o mais popular.

Existem várias formas de se incluir o bootstrap em um projeto em VueJs, prezando pela simplicidade, legibilidade e acessibilidade do artigo para todos, independente do nível de conhecimento, conduziremos simplesmente importando o arquivo css a partir do cdn.

Para isto basta editar o arquivo App.vue adicionando o @import na tag de style, da seguinte forma.

<style>
@import "https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css";
</style>

Desenvolvendo o layout da aplicação

Para o cálculo do IMC, precisaremos de duas informações apenas, a altura e o peso(massa) do usuário, então criaremos um formulário simples pedindo esses dados alterando a parte template do arquivo App.vue.

<template>
  <div class="d-flex justify-content-center">
    <div>
      <h1>Cálculo IMC</h1>

      <div class="mb-3">
        <label class="form-label">Massa em KG:</label>
        <input class="form-control" type="number">
      </div>
      <div>
        <label class="form-label">Altura em metros:</label>
        <input class="form-control" type="number">
      </div>
    </div>
  </div>
</template>

Como utilizaremos reatividade, não precisaremos de um botão para submeter esse formulário.

v-model

Agora utilizaremos uma das diretivas mais incríveis do VueJs, o v-model, dessa forma poderemos sincronizar uma variável com uma tag <input> do HTML, primeiro definiremos uma função data no corpo da tag script do VueJs que retorna as propriedades com reatividade, as propriedades que definiremos serão apenas duas: massa e altura.

<script>
export default {
  name: 'App',
  data() {
    return {
      massa: 0,
      altura: 0
    }
  }
}
</script>

Colocaremos ambas as propriedades como valor da diretiva v-model na tag <input> correspondente. Para observarmos a reatividade em ação, vamos apenas exibir ambas as propriedades na tela colocando elas em chaves duplas({{ }}).

<template>
  <div class="d-flex justify-content-center">
    <div>
      <h1>Cálculo IMC</h1>

      <div class="mb-3">
        <label class="form-label">Massa em KG:</label>
        <input v-model="massa" class="form-control" type="number">
      </div>
      <div class="mb-3">
        <label class="form-label">Altura em metros:</label>
        <input v-model="altura" class="form-control" type="number">
      </div>
      <p>Massa: {{ massa }} KG</p>
      <p>Altura: {{ altura }} metros</p>
    </div>
  </div>
</template>

Abrindo no navegador você observará a mágica acontecer, onde basta alterar o valor do input e este valor será atualizado em tempo real nos parágrafos imediatamente abaixo.

Reatividade do VueJs em ação

Propriedade computada

Agora calcularemos o IMC, existem várias formas de fazer isso, mas a mais simples é utilizando uma computed property, onde o seu valor será recalculado apenas quando alguma de suas dependências forem alteradas.

Para isso adicionaremos uma chave computed no objeto sendo exportado no arquivo App.vue, que ficará com o seguinte conteúdo.

<script>
export default {
  name: 'App',
  data() {
    return {
      massa: 0,
      altura: 0
    }
  },
  computed: {
    imc: function () {
      return this.massa / (this.altura ** 2)
    }
  }
}
</script>

Para esse valor ser visível na tela, podemos utilizar no template semelhantemente ao que foi efetuado com os atributos em data.

<template>
  <div class="d-flex justify-content-center">
    <div>
      <h1>Cálculo IMC</h1>

      <div class="mb-3">
        <label class="form-label">Massa em KG:</label>
        <input v-model="massa" class="form-control" type="number">
      </div>
      <div class="mb-3">
        <label class="form-label">Altura em metros:</label>
        <input v-model="altura" class="form-control" type="number">
      </div>
      <p>Massa: {{ massa }} KG</p>
      <p>Altura: {{ altura }} metros</p>
      <p>IMC: {{ imc }}</p>
    </div>
  </div>
</template>

Acessando o site agora e preenchendo as informações, veremos o IMC sendo atualizado e exibido na tela em tempo real.

IMC calculado em tempo real VueJs

v-if

Você provavelmente reparou que quando os dados não estão preenchidos, ou estão incorretos, como no caso da altura ser 0, um texto não muito amigável será exibido na tela, para resolver esse problema utilizaremos a diretiva v-if, que irá exibir o IMC apenas caso os valores sejam preenchidos e diferentes de zero.

Para isso, calcularemos o IMC apenas caso os dados sejam válidos, caso não sejam, retornaremos false.

<template>
  <div class="d-flex justify-content-center">
    <div>
      <h1>Cálculo IMC</h1>

      <div class="mb-3">
        <label class="form-label">Massa em KG:</label>
        <input v-model="massa" class="form-control" type="number">
      </div>
      <div class="mb-3">
        <label class="form-label">Altura em metros:</label>
        <input v-model="altura" class="form-control" type="number">
      </div>
      <p>Massa: {{ massa }} KG</p>
      <p>Altura: {{ altura }} metros</p>
      <p v-if="imc">IMC: {{ imc }}</p>
    </div>
  </div>
</template>
<script>
export default {
  name: 'App',
  data() {
    return {
      massa: 0,
      altura: 0
    }
  },
  computed: {
    imc: function () {
      if (this.massa === null || this.altura == null) {
        return false
      } else if (parseFloat(this.massa) === 0 || parseFloat(this.altura) === 0) {
        return false
      } else {
        return this.massa / (this.altura ** 2)
      }
    }
  }
}
</script>

Assim como podemos utilizar v-if, podemos utilizar a diretiva v-else para exibir um parágrafo solicitando que o usuário preencha os dados.

<template>
  <div class="d-flex justify-content-center">
    <div>
      <h1>Cálculo IMC</h1>

      <div class="mb-3">
        <label class="form-label">Massa em KG:</label>
        <input v-model="massa" class="form-control" type="number">
      </div>
      <div class="mb-3">
        <label class="form-label">Altura em metros:</label>
        <input v-model="altura" class="form-control" type="number">
      </div>
      <p>Massa: {{ massa }} KG</p>
      <p>Altura: {{ altura }} metros</p>
      <p v-if="imc">IMC: {{ imc }}</p>
      <p v-else>Preencha os dados corretamene!</p>
    </div>
  </div>
</template>

Caso os dados não estejam corretos, a mensagem será exibida ao invés do IMC.

Paragrafo condicional(v-if)

Criado um componente

Agora que já temos essa funcionalidade pronto, exploraremos uma funcionalidade muito útil do VueJs que são os componentes, para isso criaremos um arquivo no caminho src/components/ chamado CalculadoraIMC.vue com o conteúdo base de um componente.

<template>

</template>

<script>
export default {
  name: "CalculadoraIMC"
}
</script>

A estrutura de pastas agora ficou da forma mostrada abaixo.

.
├── babel.config.js
├── package.json
├── package-lock.json
├── public
│   ├── favicon.ico
│   └── index.html
├── README.md
└── src
    ├── App.vue
    ├── assets
    ├── components
    │   └── CalculadoraIMC.vue
    └── main.js

Adicionaremos o conteúdo responsável pela função da calculadora no arquivo CalculadoraIMC.vue.

<template>
  <div>
    <h1>Cálculo IMC</h1>

    <div class="mb-3">
      <label class="form-label">Massa em KG:</label>
      <input v-model="massa" class="form-control" type="number">
    </div>
    <div class="mb-3">
      <label class="form-label">Altura em metros:</label>
      <input v-model="altura" class="form-control" type="number">
    </div>
    <p>Massa: {{ massa }} KG</p>
    <p>Altura: {{ altura }} metros</p>
    <p v-if="imc">IMC: {{ imc }}</p>
    <p v-else>Preencha os dados corretamene!</p>
  </div>
</template>

<script>
export default {
  name: "CalculadoraIMC",
  data() {
    return {
      massa: 0,
      altura: 0
    }
  },
  computed: {
    imc: function () {
      if (this.massa === null || this.altura == null) {
        return false
      } else if (parseFloat(this.massa) === 0 || parseFloat(this.altura) === 0) {
        return false
      } else {
        return this.massa / (this.altura ** 2)
      }
    }
  }
}
</script>

Agora vamos importar e utilizar esse componente no arquivo App.vue.

<template>
  <div class="d-flex justify-content-center">
    <CalculadoraIMC></CalculadoraIMC>
  </div>
</template>
<script>

import CalculadoraIMC from "@/components/CalculadoraIMC";

export default {
  name: 'App', components: {CalculadoraIMC}
}
</script>

<style>
@import "https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css";
</style>

Dessa forma temos todas as funcionalidades da calculadora em apenas uma linha, e podemos utilizar o mesmo componente em várias páginas ou múltiplas vezes na mesma página.

binding de classe

Às vezes queremos dar destaque para uma mensagem dependendo do seu valor, no exemplo da calculadora de IMC poderíamos deixar o texto do parágrafo destacado caso o IMC seja maior que trinta, para isso podemos fazer um biding de classe, utilizando a classe text-warning do bootstrap.

Abaixo temos essa alteração efetuada no arquivo CalculadoraIMC.vue.

<template>
  <div>
    <h1>Cálculo IMC</h1>

    <div class="mb-3">
      <label class="form-label">Massa em KG:</label>
      <input v-model="massa" class="form-control" type="number">
    </div>
    <div class="mb-3">
      <label class="form-label">Altura em metros:</label>
      <input v-model="altura" class="form-control" type="number">
    </div>
    <p>Massa: {{ massa }} KG</p>
    <p>Altura: {{ altura }} metros</p>
    <p v-if="imc" :class="{'text-warning': imc > 30}">IMC: {{ imc }}</p>
    <p v-else>Preencha os dados corretamene!</p>
  </div>
</template>

O resultado caso o IMC seja maior que 30 será como mostrado na imagem abaixo.

Biding de classe VueJs

binding de estilo

Outra forma de ter um resultado semelhante ao do tópico anterior é utilizando o binding de estilo.

Nesse caso adicionaremos a propriedade css color com o valor red caso o IMC seja maior que 30, essa alteração será realizada no arquivo CalculadoraIMC.vue.

<template>
  <div>
    <h1>Cálculo IMC</h1>

    <div class="mb-3">
      <label class="form-label">Massa em KG:</label>
      <input v-model="massa" class="form-control" type="number">
    </div>
    <div class="mb-3">
      <label class="form-label">Altura em metros:</label>
      <input v-model="altura" class="form-control" type="number">
    </div>
    <p>Massa: {{ massa }} KG</p>
    <p>Altura: {{ altura }} metros</p>
    <p v-if="imc" :style="{'color': imc > 30 ? 'red' : 'black'}">IMC: {{ imc }}</p>
    <p v-else>Preencha os dados corretamene!</p>
  </div>
</template>

O resultado caso o IMC seja acima de 30 ficará como mostrado na imagem abaixo.

Biding de estilo VueJs

Obrigado por visitar o blog e por ler esse artigo, se tive qualquer dúvida, ideia ou sugestão, não hesite em entrar em contato pelo meu e-mail: lindomar@covildodev.com.br