VueJS
Tutorial passo a passo de como trabalhar com Vue, criar rotas, componentes e páginas.
Inicio
Esta página contém um rápido tutorial que poderá servir de apoio para o desenvolvimento de qualquer aplicação front-end com VueJS.
O principal objetivo desse guia é explicar como funciona o fluxo em uma aplicação com o framework da forma mais prática possível. Portanto, não é seguido o guia de melhores práticas.
Como base, será utilizado uma simples aplicação de autenticação com cadastro e login. O código completo pode ser encontrado no seguinte repositório:
- Aplicação: https://marlonfurtado.github.io/vuejs-auth/
- Repositório: https://github.com/marlonfurtado/vuejs-auth
Pré-Requisitos
- NodeJs e NPM (obrigatório)
- Editor Visual Studio Code (recomendável)
- Extensão para o VS Code: Vetur (recomendável)
- Abra o editor
-
Ctrl + Shift + X, para abrir as extensões - Procure por
Vetur - Clique em
install, e depoisreload.
1. Estrutura do projeto
Em uma estrura com vue-loader e webpack, como a que estamos usando no projeto Arbitrium, a criação de páginas, componentes e o desenvolvimento da aplicação se resumem em basicamente três pastas (não serão as únicas, mas as principais no processo de desenvolvimento). São elas:
- /src/components/
- /src/pages/
- /src/router/
1.1. Components
/src/components/
// TODO
1.2. Pages
/src/pages/
// TODO
1.3. Router
/src/router/
// TODO
2. Passo a Passo
O componente usado como exemplo é o de uma notificação de erro, caso o usuário digite seus dados errados ou aconteça algum erro com o banco de dados.
2.1 Criando uma página
Para criar uma página é simples.
-
Na pasta
src/pages/crie um arquivo com a extensão.vue. O nome do arquivo, preferencialmente, deve ser o mesmo do nome da rota que será acessado na URL. Aqui criaremos o uma páginaTest.vue. -
Dentro do arquivo, crie o template inicial:
<template>
<!-- HTML -->
</template>
<script>
// JS
</script>
<style>
/* CSS */
</style>
- A página terá apenas um input de senha e um botão.
<template>
<div class="row mt-4">
<div class="col-md-5"></div>
<div class="form-inline">
<div class="form-group mx-sm-3 mb-2">
<label for="password" class="sr-only">Password</label>
<input type="password" class="form-control" id="input-password" placeholder="Password">
</div>
<div class="col-md-7 ml-1 mt-1">
<button class="btn btn-primary mb-2">Confirm identity</button>
</div>
</div>
</div>
</template>
- Agora é preciso iniciar a instância Vue dentro do
<script>. Ainda sem muita lógica.
export default {
name: "Test",
data: () => {
return {}
}
}
- Como estamos usando Bootstrap para essa página, então não foi preciso mexer na tag
<style>.
2.2 Criando uma rota
Com a página criada é preciso criar uma rota para poder acessá-la.
- Em
src/router/index.jsé onde fica o arquivo que gerencia as rotas e cada página da aplicação. - Se a aplicação foi criada com o
vue-cli(caso do Arbitrium), então já deve ter uma estrutura criada com uma instância deRoute. Algo como:let router = new Router({ router: [] }), onde o argumento passado dentro deRouteré um array com o caminho de todas as rotas do projeto. Como no exemplo abaixo.
import Home from '@/components/Home'
import Login from '@/components/Login'
let router = new Router({
routes: [
{
path: '/home',
name: 'Home',
component: Home,
meta: {
requireAuth: true
}
},
{
path: '/login',
name: 'Login',
component: Login
},
]
})
- Nesse arquivo é necessário apenas importar a nova página (ou componente) e criar um novo objeto dentro do array com as informações do novo caminho.
import Test from '@/pages/Test'
routes: [
{
path: '/test',
name: 'Test',
component: Test
}
]
- Para testar a nova rota é só acessá-la no seu navegador (provavelmente em http://localhost:8080/test)
2.3 Criando um componente
-
Dentro da pasta
/src/components/crie um arquivo com a extensão.vue. O nome do arquivo deve ser o nome do componente de forma que facilite sua identificação. Por exemplo, um componente que retorna um erro, pode ser chamado deErrorNotification.vue -
Dentro do arquivo, crie o template inicial do componente (o mesmo que foi visto para criar uma página). Esse é o template padrão que usaremos para todos arquivos com a extensão
.vue. -
Começando pelo HTML. Como o componente é simples, uma
<div>com as mensagens de erro dentro, e um<button>para fechar a notificação são o suficiente.
1. <template>
2. <div id="notification" class="alert alert-danger">
3. <button @click="close()" class="close"><span aria-hidden="true">×</span></button>
4. <p>Code: {{code || '0'}}</p>
5. <p>{{message || 'Sorry, an error occurred.'}}</p>
6. <p>Try again, or <router-link to="/signup">create account.</router-link></p>
7. </div>
</template>
- A tag
<script>é onde está todo o comportamento do componente. E o modelo padrão é sempre algo como:
<script>
1. export default {
2. name: 'ErrorNotification',
3. props: ['code', 'message'],
4. data: () => {
5. return {}
6. },
7. methods: {
8. close: function() {
9. document.querySelector('#notification').classList.add('d-none')
10. }
11. }
12. }
</script>
- O
export default { ... }(linha 1) é como se fizesse umexport new Vue({}). Ou seja, o que está dentro de{ ... }são os objetos ou métodos de uma instância de Vue.js - O
data(linha 4) são os dados que circulam no componente. Esse é um dos pontos principais da reatividade de Vue. Deve ser sempre uma função que retorna um objeto. Por exemplo, como teste, você pode criar uma variável dentro dedatae mostrar ela na tela.
data: () => {
return {
message: 'Hello World!',
}
},
Com a variável criada, é só colocar ela no HTML com a sintaxe: {{message}}. Exatamente como é no Angular.
-
O
props(linha 3) deve ser um array, e assim como no React.js, são os dados que vem do elemento pai e é colocado no componente como se fosse um atributo normal. Será usado mais a frente para pegar o código e a mensagem de erro. -
O
methods(linha 7) também será bastante usado. Dentro dele vai os métodos que serão usados no componente. Por exemplo, ao clicar no botão de fechar, o métodoclose()é chamado para fechar a notificação.
Veja mais em: https://medium.com/emanuelg-blog/descomplicando-os-single-file-components-do-vue-js-2df16724baab
2.3 Chamando o componente na página
-
Com o componente pronto, agora é preciso chamá-lo na nossa página. Para isso, vá no arquivo da pagina de Test, dentro da tag de
<script> -
Primeiro é preciso importar o componente:
import ErrorNotification from '../components/ErrorNotification' -
E depois declarar o componente no objeto
components:
components: { ErrorNotification }, -
Em
dataé onde vai nossas variáveis, por exemplo: password, ErrorCode e ErrorMessage -
E para finalizar o script é preciso criar nosso método de validação que é onde vai estar a lógica para mostrar o componente. Se errar a senha, então as variáveis recebem um valor, e esse valor é passado para o componente mostrar o erro e a mensagem. Por exemplo, a função validate() é criada abaixo e depois chamada no HTML. (código completa mais abaixo)
methods: {
validated: function() {
if (this.password !== 'password') {
this.errorCode = 666
this.errorMessage = "Senha inválida"
}
else {
this.errorCode = null
this.errorMessage = null
}
}
}
- Com todo o script de controle da página pronto, agora é arrumar o HTML. O template final do HTML fica como abaixo:
1. <template>
2. <div class="row mt-4">
3. <div class="col-md-5"></div>
4. <div class="form-inline">
5. <div class="col-md-7 ml-1 mt-1">
6. <div class="form-group mx-sm-3 mb-2">
7. <label for="password" class="sr-only">Password</label>
8. <input type="password" v-model="password" class="form-control" id="input-password" placeholder="Password">
9. </div>
10. </div>
11. <div class="col-md-5 ml-1 mt-1">
12. <button @click="validated()" class="btn btn-primary mb-2">Confirm identity</button>
13. </div>
14. </div
15. <!-- ERROR NOTIFICATION -->
16. <ErrorNotification v-show="errorCode" :code="errorCode" :message="errorMessage"></ErrorNotification>
17. </div>
18. </template>
-
As classes utilizadas são todas do Bootstrap, e a maioria dessas são para alinhamento, para mais informações pode ser consultado a documentação do Bootstrap.
-
Na linha 8 é onde está o input de password com a diretiva
v-model, exatamente como no Angular, essa diretiva é responsável por fazer a conexão (two-way data biding) de um dado no HTML para o tratamento no script. No exemplo estamos passando a senha que o usuário digitar para o atributopassworddentro de data() no script. -
A linha 12 é um botão com a diretiva
@clickque captura a ação do usuário. Quando clicar no botão a função validated() é chamada. -
Na linha 16 é onde chamamos o componente de erro que foi criado. O componente funciona como uma tag de HTML normal podendo receber inclusive class ou id. No exemplo, o componente tem uma diretiva
v-showque é uma condição para ele ser exibido. Se aquela variável fortrue, então o componente é mostrado. A variávelerrorCodetambem está presente na funçãodata()no script e é atribuido um valor quando a funçãovalidated()é chamada. -
Ainda na linha 16 tem
:codee:messageque funcionam como parâmetros passados para o componente. No exemplo, passamos os atributos de erro, que no arquivo de componenteErrorNotification.vueeles são tratados noprops: ["code", "message"]. -
O resultado final da página ficou como abaixo:
<template>
<div class="row mt-4">
<div class="col-md-5"></div>
<div class="form-inline">
<div class="col-md-7 ml-1 mt-1">
<div class="form-group mx-sm-3 mb-2">
<label for="password" class="sr-only">Password</label>
<input type="password" v-model="password" class="form-control" id="input-password" placeholder="Password">
</div>
</div>
<div class="col-md-5 ml-1 mt-1">
<button @click="validated()" class="btn btn-primary mb-2">Confirm identity</button>
</div>
</div>
<!-- ERROR NOTIFICATION -->
<ErrorNotification v-show="errorCode" :code="errorCode" :message="errorMessage"></ErrorNotification>
</div>
</template>
<!-- SCRIPTS -->
<script>
import ErrorNotification from '../components/ErrorNotification'
export default {
name: "Test",
components: {
ErrorNotification
},
data: () => {
return {
password: '',
errorCode: null,
errorMessage: null
}
},
methods: {
validated: function() {
if (this.password !== 'password') {
this.errorCode = 666
this.errorMessage = "Senha inválida"
}
else {
this.errorCode = null
this.errorMessage = null
}
}
}
}
</script>

