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 dedata
e 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 atributopassword
dentro de data() no script. -
A linha 12 é um botão com a diretiva
@click
que 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-show
que é uma condição para ele ser exibido. Se aquela variável fortrue
, então o componente é mostrado. A variávelerrorCode
tambem está presente na funçãodata()
no script e é atribuido um valor quando a funçãovalidated()
é chamada. -
Ainda na linha 16 tem
:code
e:message
que funcionam como parâmetros passados para o componente. No exemplo, passamos os atributos de erro, que no arquivo de componenteErrorNotification.vue
eles 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>