slides.com/renanthompsom/vuejs

Introdução ao Vue.js

Renan Gabriel

@github

@linkedin

@facebook

Ministrantes

O que é o Vue.js?

Vue (pronuncia-se /vjuː/, como view, em inglês) é um framework progressivo para a construção de interfaces de usuário.

Por que aprender

Vue.js?

Por que aprender Vue.js?

  • Open Source;
  • Acessível (HTML, CSS e JavaScript);
  • Versátil;
  • Performático;
  • Escalável (reuso de componentes);
  • Curva de aprendizado baixa;
  • Fácil integração.

O criador - Evan You

Desenvolvimento do Vue - Linha do tempo

  • 2013: Evan começa o Vue no seu tempo livre enquanto trabalhava no Google.
  • 2015: Evan gasta todos os dias de suas férias para lançar a v1.0 em Outubro.
  • 2016: Evan começa a trabalhar em tempo integral no Vue, financiado pelo Patreon.
  • 2018: Evan contrata seus primeiros empregados para corrigir bugs.
https://www.patreon.com/evanyou

Evan You - Patreon

Meme Generator

Meme Generator

Tópicos

  1. A instância Vue
  2. Ciclo de vida da instância Vue
  3. Dados computados
  4. Renderização condicional
  5. Interligações de atributos
  6. Interligações de formulários
  7. Manipulação de eventos
  8. Renderização de listas
  9. Interligações de classe e estilo
  10. Componentes
  11. Eventos customizados
  12. Desafios

Requisitos mínimos

  • Conhecimentos básicos de HTML, CSS, e JavaScript.
  • Experiência anterior com outros frameworks ajuda, mas não é necessária.

Vue.js devtools

componentes

Vue.js devtools

eventos

Vue.js devtools - links

Vue.js devtools - config

1. A Instância Vue

Nesse tópico, vamos aprender como usar o Vue para exibir dados em uma página web.

Objetivo

Vamos adicionar o título de nossa aplicação.

Código inicial

index.html

main.js

<!DOCTYPE html>
<html>
  <head>
    <title>Meme Generator</title>
  </head>
  <body>
    <div id="app">
      <h1>Meme Name</h1>
    </div>
    
    <script src="./assets/js/main.js"></script>
  </body>
</html>
let meme = 'Dog Meme';

Problema

Nós precisamos de alguma forma mostrar o valor da variável meme dentro do <h1> no nosso html.

index.html

<script src="https://unpkg.com/vue"></script>

O primeiro passo é incluir o script do Vue no nosso projeto.

Solução

E assim usar a nossa primeira expressão JavaScript

index.html

main.js

E no nosso main.js, vamos incluir a instância do Vue

const app = new Vue({
  el: '#app',
  data: {
    meme: 'Dog'
  }
})
<div id="app">
  <h1>{{ meme }}</h1>
</div>

Vamos ver o nome Dog dentro de nossa tag <h1>

Resultado

WTF?

A Instância Vue

A instância Vue é a raiz de nossa aplicação. Ela é criada passando um objeto com suas opções.

 

Nesse objeto tem uma variedade de propriedades opcionais que dão a instância a habilidade de armazenar dados e realizar ações.

 
  const app = new Vue({options})

Conexão com um elemento 

A instância Vue é então conectada com um elemento de sua escolha, formando um relacionamento entre a instância e uma parte do DOM (Document Object Model).

Em outras palavras, nós estamos ativando o Vue na div com o id app, colocando '#app', como o elemento (el) da nossa instância.

  el: '#app'

DOM - Document Object Model 

Propriedade 'data' 

Uma instância do Vue possui a propriedade data para inserir os dados

Os dados da instância podem ser acessados dentro do elemento em que a instância está plugada.

  data: {
    meme: 'Dog'
  }
<div id="app">
  <h1>{{ meme }}</h1>
</div>

Usando a expressão {{ }}

Se nós queremos que algum dado seja mostrado no html, é preciso adicionar as chaves duplas entre o valor a ser exibido.

  <h1>{{ meme }}</h1>

Termo importante: Expression

  • Expressões permitem utilizar valores existentes de dados, em conjunto com lógica, para produzir novos valores de dados.
  • Quando o Vue visualiza a expressão {{ meme }}, ele reconhece que nós estamos referenciando aos dados de sua instância, e ele substitui aquela expressão com o seu devido valor, no nosso caso o nome do meme que é: "Dog".

Expression

Expressões - outros exemplos

  {{ title.toUpperCase() }}
  {{ firstName + ' ' + lastName }}
  {{ ok ? 'SIM' : 'NÃO' }}

Reatividade

  • A razão do Vue ser capaz de mostrar o valor dos dados imediantamente é porque o Vue é reativo.
  • Em outras palavras, os dados da instância estão interligados a cada local em que o dado está sendo referenciado.

Para provar isso, vamos abrir o console e alterar o valor de nossa string meme. Vamos ver o que acontece.

Reatividade

Busquem conhecimento!!

1. A instância Vue

 

  • Como começar a escrever uma aplicação Vue utilizando sua instância;
  • Como exibir dados em uma página web;
  • A instância Vue é a raiz de toda aplicação Vue;
  • A instância Vue é conectada com um elemento do DOM;
  • Os dados da instância Vue podem ser mostrados usando uma sintaxe de chaves duplas. Ex: {{ title }};
  • Vue é reativo.

O que aprendemos

1º DESAFIO

  • Renomear a propriedade meme do objeto data para title, e alterar seu valor para : "Meme Generator".

2. Ciclo de Vida da Instância Vue

Nesse tópico, vamos entender como que funciona o ciclo de vida da instância Vue.

Objetivo

Vamos adicionar o valor do título da página (Meme Generator), somente após a instância for criada.

Ciclo de Vida da Instância

  • Cada instância Vue passa por uma série de etapas em usa inicialização - (configurar a observação de dados, compilar o template, montar a instância no DOM, atualizar o DOM quando os dados forem alterados).
  • Ao longo do caminho, ocorre a invocação de alguns gatilhos de ciclo de vida, oferecendo a oportunidade de executar lógicas personalizadas em etapas específicas.

  beforeCreate() {},
    
  created() {},
    
  beforeMount() {},
    
  mounted() {},
    
  beforeUpdate() {},
    
  updated() {},
    
  beforeDestroy() {},
    
  destroyed() {},

Gatilhos do ciclo de vida da instância

Ciclo de Vida da Instância

 
  data: {
    title: 'Meme Generator',
  },
    
  created() {
    console.log('created');
  },

Por exemplo, o gatilho created pode ser utilizado para executar código logo após a instância ser criada:

Diagrama do Ciclo de Vida

2. Ciclo de vida da instância Vue

 

  • A instância Vue, possui gatilhos que permite adicionar códigos específicos durante a criação de sua instância.

O que aprendemos

2º DESAFIO

  • Na propriedade data, atribuir o valor de title para '  '.
  • Adicionar o valor de title (Meme Generator), no gatilho created da instância.
 
  data: {
    title: '',
  },
    
  created() {
    // setar o title;
  },

3. Dados computados

Nesse tópico vamos aprender sobre dados computados, que são propriedades da instância do Vue que calculam valores.

Objetivo

Vamos formatar nosso título de Meme Generator para Meme-Generator, salvando esse valor em um dado computado.

Problema

Queremos formatar nosso título, porém adicionar qualquer lógica mais complexa, pode fazer com que nosso HTML fique com uma manutenção mais complicada. Por exemplo:

<div id="app">
  <h1>{{ title.replace(' ', '-') }}</h1>
</div>

Solução

Desde que dados computados calculam um valor no lugar de armazenar um valor, vamos adicionar a opção para dados computados em nossa instância:

Quando o newTitle é chamado, ele faz o replace da string retornando o novo valor. Se o title for atualizado, o dado computado vai atualizar, caso contrário seu valor vai ficar salvo em cache.

data: {...},

computed: {
  newTitle() {
    return this.title.replace(' ', '-');
  },
},

Resultado

<div id="app">
  <h1>{{ newTitle }}</h1>
</div>

Outros exemplos

computed: {
  fullName() {
    return this.firstName + ' ' + this.lastName;
  },
  
  showUrl() {
    return `${this.url}/${this.id}`;
  }
}

3. Dados Computados

 

  • Dados computados calculam valores;
  • Dados computados são cacheados, o seu valor só é atualizado quando uma das dependências é atualizada.

( O que aprendemos)

3º DESAFIO

  • Remover o dado computado chamado newTitle.
  • Criar um novo dado computado, chamado titleFormatted que retorne o título em letras maiúsculas.

4. Renderização condicional

Nesse tópico, vamos explorar maneiras de renderizar condicionalmente algum elemento.

Objetivo

Vamos adicionar uma condição que vai definir se vamos ou não mostrar o título de nossa aplicação.

Problema

  • Frequentemente em uma página web, nós queremos que um elemento apareça na página dependendo de alguma condição específica.

Solução - (V-if)

  • A solução do Vue é muito simples, nós podemos usar a diretiva v-if  / v-else que determina qual elemento ele vai renderizar.
<h1 v-if="showTitle">
  {{ titleFormatted }}
</h1>
data: {
  showTitle: true
}

Alternando o valor de showTitle para false

data: {
  showTitle: false
}

V-if / V-else

  <div v-if="emptyTable()">
    Nenhum resultado encontrado!
  </div>
  <div v-else>
    <table></table>
  </div>

V-if / V-else-if / V-else

  <div v-if="isProfessor()">
    <h1>Professor</h1>
  </h1>
  <div v-else-if="isVeterano()">
    <p>Veterano</p>
  </div>
  <div v-else>
    <p>Calouro</p>
  </div>

V-show

  • Se nosso aplicativo tem um elemento que frequentamente é mostrado ou não, é melhor utilizar a diretiva v-show.
  • Na diretiva v-show o elemento sempre vai estar disponível no DOM, o que vai alterar é apenas sua visibilidade, sendo a propriedade (display: none;).
  • Esse método é mais performático do que inserir ou remover um elemento do DOM várias e várias vezes com o v-if / v-else.
<div v-show="isLoading">
  <loader />
</div>

4. Renderização condicional

 

  • Diretivas do Vue para condicionalmente renderizar elementos (v-if / v-else-if / v-else / v-show);
  • O elemento só é exibido se a condição dentro da diretiva for verdadeiro;
  • Você pode invocar métodos que contém expressões dentro das condições dessa diretiva;
  • V-show apenas muda a visibilidade do elemento, ele não insere ou remove um elemento do DOM.

( O que aprendemos)

4º DESAFIO

  • Adicionar uma propriedade chamada 'description' no objeto data, com a descrição do app.
  • Adicionar a tag <p> abaixo do <h1> mostrando a descrição do app.
  • Adicionar uma propriedade chamada showDescription, que vai ter um valor booleano (true/false).
  • Adicionar uma diretiva condicional do Vue, que se encaixa nessa situação para mostrar ou não, a descrição do app.

5. Interligações de atributos

Objetivo

Vamos conectar o link de uma imagem

com o elemento <img> em seu atributo src, para mostrar alguma imagem de um meme específico.

Nesse tópico, vamos explorar maneiras de conectar dados aos atributos de elementos HTML.

Encontrar uma imagem - (meme)

Código inicial

index.html

Nós queremos que os dados da imagem, sejam dinamicamente conectados.

Dado do caminho da imagem.

main.js

<div id="app">
  <h1 v-if="showTitle">
    {{ titleFormatted }}
  </h1>

  <img src="">
</div>
const app = new Vue({
  el: '#app',
  data: {
    title: '',
    image: {
      path: './assets/images/dog-meme.png'
    },
  }
})

Problema

  • Nós queremos que a imagem apareça na página, porém de forma dinâmica.
  • Dessa maneira, queremos ser capazes de atualizar o source da imagem pelo nosso objeto data e a imagem ser atualizada automaticamente na nossa página.
  • Como nosso atributo src da tag <img> é o que encontra o caminho da imagem, nós precisamos que o nosso dado seja interligado com esse atributo src.

Solução

Para víncular o valor do src da imagem no nosso objeto data com nossa tag img, nós vamos usar a diretiva v-bind do Vue.

v-bind

O que vai ser avaliado como:

  <img :src="image.path">
  <img src="./assets/images/dog-meme.png">

Termo importante: Data Binding

  • Quando falamos de Data Binding no Vue, nós queremos dizer que os lugares do HTML que estão ligados e mostrando dados no Vue, estão diretamente conectados com os dados do Vue.

Data Binding

  <img :src="image.path">
data: {
  image: {
    path: './assets/images/dog-meme.png'
  },
}

index.html

main.js

Resultado

Alterando a imagem

Se o path da imagem for alterado o src vai atualizar, e a nova imagem vai aparecer.

Isso acontece devido ao src da imagem, estar vinculado com nosso objeto data. (Data Binding)

 
  image: {
    path: 'https://imgflip.com/s/meme/Scared-Cat.jpg'
  }

Outros tipos de v-bind

 
 <a :href="link">Link</a>
 
  <div :class="divClass">Div</div>
 
  <span :title="tooltip">Span</span>
 
  <button :disabled="isDisabled">Button</button>

5. Interligações de atributos


  • Dados podem ser vinculados a elementos HTML;
  • Sintaxe para o bind é v-bind ou sua abreviação ':'    ;
  • O nome do atributo vem depois do :     especifica o atributo em que estamos realizando o bind;
  • Dentro das aspas dos atributos, está o dado em que estamos referenciando.

v-bind

:

O que aprendemos

:

5º DESAFIO

  • Adicione um item chamado title dentro do objeto image.
  • Realize o v-bind com o atributo title da tag  img adicionando o título do meme.

6. Interligações em formulários

Nesse tópico, vamos aprender como realizar interligações em formulários.

Objetivo

Vamos adicionar um input que será utilizado para escrever sobre a imagem e realizar essa conexão com o que foi digitado.

#main-content {
  word-wrap: break-word;
}

#main-image {
  width: 100%;
  height: auto;
  max-height: 800px;
}

.text {
  color: #fff;
  font-size: 4.5vw;
  line-height: 3.8vw;
  padding: 15px;
  position: absolute;
  text-transform: uppercase;
  text-shadow: 3px 3px 3px #000;
}

Código inicial - Criar o CSS

assets/css/style.css

Código inicial

Incluir meta tags e  bootstrap 4

<head>
  <!-- Meta tags -->
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <!-- Bootstrap 4 CSS -->
  <link rel="stylesheet" href="https://bootswatch.com/4/lux/bootstrap.min.css">
  <!-- Style -->
  <link rel="stylesheet" href="./assets/css/style.css">
  <!-- Vue.js -->
  <script src="https://unpkg.com/vue"></script>
  <title>Meme Generator</title>
</head>

Bootstrap 4 - Theme Lux

Customizar layout e adicionar input

  <body>
    <div id="app" class="row m-0 py-2 text-center">
      <div id="main-content" class="col-md-6 d-block mx-auto position relative">
        <img id="main-image" :src="image.path" :title="image.title">
      </div>

      <div class="col-md-6">
        <h1 v-if="showTitle" class="mt-2">
          {{ titleFormatted }}
        </h1>

        <div class="form-group">
          <input type="text" placeholder="Top text" class="form-control">
        </div>
      </div>
    </div>

    <script src="./assets/js/main.js"></script>
  </body>

Layout

Texto do input

<p class="fixed-top text">Top text</p>

<img id="main-image" :src="image.path" :title="image.title">

Problema

Como fazer a conexão entre o que digitamos no input, e o texto acima da imagem?

Solução

Precisamos fazer uma interligação entre o input e o elemento <p> acima da nossa imagem usando a diretiva v-model do Vue.

Diretiva V-model

  • Você pode usar a diretiva v-model para criar interligações de mão dupla (two-way data binding) entre os dados e elementos como input, textarea e select de formulários.

Alterar a view atualiza o model

Alterar o model atualiza a view

Two-Way Data Binding

Diretiva V-model

data: {
  text: {
    top: '',
  }
},

main.js

 <div class="form-group">
   <input
     type="text"
     placeholder="Top text"
     class="form-control"
     v-model="text.top"
   >
</div>
<p class="fixed-top text">
  {{ text.top }}
</p>

index.html

index.html

Resultado

Alterar a fonte

  • Adicionar uma fonte diferente para o texto do meme - Google Fonts.
  • Adicionar a fonte no arquivo style.css, dentro da classe .text (especificar o font-family)

Alterar a fonte - Passion One

<link href="https://fonts.googleapis.com/css?family=Passion+One&display=swap" rel="stylesheet">

index.html

.text {
  ...,
  font-family: 'Passion One';
  ...
}

style.css

Resultado

6. Interligações em formulários

 

  • A diretiva v-model permite utilizar interligações de mão dupla (two-way data binding).

( O que aprendemos)

6º DESAFIO

  • Adicionar um input do tipo texto, abaixo do top input text com o placeholder = Bottom text.
  • Adicionar uma propriedade chamada bottom, dentro do objeto text.
  • Adicionar uma tag <p> abaixo da imagem com a classe "fixed-bottom text".
  • Realizar o two-way data binding (v-model) entre o input e essa tag <p>;

6º DESAFIO

7. Manipulação de eventos

Nesse tópico, vamos aprender como ouvir eventos do DOM para que possamos invocar métodos.

Objetivo

Vamos adicionar um botão chamado reset que quando for clicado, vai limpar o texto dos inputs.

Problema

Nós precisamos de um botão reset para ouvir eventos de click, para então acionar um método que vai limpar o formulário.

Solução

Vamos adicionar o botão com a diretiva v-on do Vue que permite ouvir eventos do DOM, e invocar um método nosso que vai limpar o formulário.

Adicionar o botão

Vamos adicionar o botão abaixo dos inputs

Nós estamos usando a diretiva v-on abreviada = @ para ouvir o evento de click e acionar o método resetInputs()

v-on

@


  <button
    class="btn btn-outline-primary"
    @click="resetInputs()"
  >
    Reset
  </button>

Outros tipos de eventos

// elemento recebeu o foco
@focus="method" 

// elemento perdeu o foco
@blur="method"

// botão de submit pressionado
@submit="method"

// qualquer tecla foi pressionada
@keydown="method" 

// a tecla foi solta
@keyup="method"

Propriedade methods

A instância Vue tem uma propriedade opcional para seus métodos. Então nós vamos adicionar o método resetInputs que realiza a ação de limpar o formulário


  methods: {
    resetInputs() {
      this.text.top = '';
      this.text.bottom = '';
    },
  },

ES6 - Sintaxe

No lugar de escrever o método como

 

 nós podemos escrever usando a abreviação do ES6 sendo:

 

 São duas maneiras equivalentes de escrever uma função.

  resetInputs() {}
  resetInputs: function() {}

Resultado

7. Manipulação de eventos

( O que aprendemos)

 

  • A diretiva v-on é usada para permitir que os elementos ouçam os eventos do DOM;
  • A abreviação da diretiva v-on é @;
  • Você pode especificar o tipo de evento que quer ouvir (click, mouseover, qualquer outro evento do DOM) para invocar seus métodos.

8. Renderização de listas

Nesse tópico, vamos aprender como mostrar listas em nossas páginas usando o Vue.

Objetivo

Mostar uma lista com as cores disponíveis para o texto.

Código inicial

  data: {
    colors: ['black', 'red', 'white'],
  },

main.js

Problema

  • Nós precisamos de uma maneira de mostrar as cores para que o usuário possa selecionar, qual que ele deseja ser a cor do texto.
  • Como nós podemos iterar o array de cores e mostrar na nossa página?
  colors: ['black', 'red', 'white']

main.js

Solução (V-for)

index.html

<div class="form-group">
  <label>TEXT COLOR</label>
  <span v-for="color in colors">
    <span class="ml-2">
      {{ color }}
    </span>
  </span>
</div>
  • Outra diretiva do Vue chamada v-for que permite iterar um array para então podermos renderizar os dados dele.
  • Vamos adicionar o código abaixo dos inputs.
  • Agora temos o nome das cores sendo mostradas, mas como isso está funcionando?

  <div v-for="(item, index) in array">
    <p>{{ item + '-' + index }}</p>
  </div>

 data: {
   array: ['Fist', 'Second', 'Third']
 }

html

js

Diretiva v-for (arrays)

  <h1>Students</h1>
  <p v-for="student in students">
    {{ student.name }}
  </p>

 data: {
   students: [
     { id: 1, name: 'Renan' },
     { id: 2, name: 'Pedro' },
   ]
 }

Diretiva v-for (array de objetos)

js

html

Diretiva v-for (array de objetos)

  • Nota que é recomendado usar um atributo key   quando for utilizar o v-for, para que  o Vue possa manter a identidade de cada item.

:key


  <h1>Students</h1>

  <p
    v-for="student in students"
    :key="student.id"
  >
    {{ student.name }}
  </p>

html

Adicionar o atributo :key

<div class="form-group">
  <label>TEXT COLOR</label>
  <span
    v-for="(color, index) in colors"
    :key="index"
  >
    <span class="ml-2">
      {{ color }}
    </span>
  </span>
</div>

index.html

8. Renderização de listas

 

  • A diretiva v-for permite iterar um array para mostrar os dados;
  • Nós usamos um apelido para o elemento do array que está sendo iterado, e também especificamos o nome do array em que estamos iterando. Ex: v-for="item in items";
  • Nós podemos percorrer um array de objetos e usar a notação de ponto, para acessar os valores dos objetos;
  • Quando é usado o v-for é recomendado atribuir uma chave unica a cada elemento em seu atributo :key.

( O que aprendemos)

9. Interligações de classe e estilo

Nesse tópico, vamos aprender como estilizar dinamicamente nosso HTML, realizando a interligações com o atributo style dos elementos e também sua classe.

Objetivo

Adicionar o background do span com a devida cor do array.

Sintaxe de Objeto

<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>

Você pode usar camelCase ou kebab-case para o nome da propriedade CSS.

A sintaxe Array para v-bind:style permite que você aplique múltiplos objetos de estilo para o mesmo elemento:

<div :style="[baseStyles, overridingStyles]"></div>

Sintaxe de Array

Interligação de estilo

Sintaxe de Objeto

<div :class="{ active: isActive }"></div>

Podemos passar um objeto para o v-bind:class para alternar classes dinamicamente:

data: {
  isActive: true
}
<div class="active"></div>

Que vai renderizar no HTML:

Interligação de Classe

Interligação de Classe

  data: {
    activeClass: 'active',
    errorClass: 'text-danger'
  }

Que renderizará:

<div class="active text-danger"></div>

Também é possível utilizar uma expressão ternária

<div :class="[isActive ? activeClass : '']"></div>
<div :class="[activeClass, errorClass]"></div>

Sintaxe de Array

Problema

  • Nós precisamos de alguma maneira mostrar o background da cor de acordo com o nome da mesma.
  • Vamos usar a interligação de estilo inline para dinamicamente setar o background de nosso span, baseado no nosso array de cores.

Solução

  :style="{ color: 'red' }"

Solução

Vamos passar a cor para a propriedade do css color.

<div class="form-group">
  <label>TEXT COLOR</label>
  <span
    v-for="(color, index) in colors"
    :key="index"
  >
    <span
      id="span-color"
      :style="{ background: color }"
    >
    </span>
  </span>
</div>

index.html

#span-color {
  border: 1px solid #000;
  border-radius: 50%;
  cursor: pointer;
  display: inline-block;
  width: 16px;
  height: 16px;
  margin-left: 3px;
}

style.css

Resultado

9. Interligações de classe e estilo

 

  • Os elementos HTML podem ser interligados com sua classe ou com seu atributo style de forma dinâmica;
  • Nós podemos usar expressões dentro da interligação de classes para  avaliar se devemos mostrar uma classe.

( O que aprendemos)

7º DESAFIO

  • Adicionar uma propriedade color no objeto text com o valor: 'white';
  • Adicionar uma propriedade computada chamada textColor, com o corpo do método:                                                 
  • Realizar uma interligação de estilo, com as tags <p> e o dado computado textColor = <p :style="textColor"
  • Adicionar um método chamado updateTextColor(color), que quando o <span id="span-color"> for clicado, enviar para esse método a cor, e atualizar a cor do texto: this.text.color = color;
  return { color: this.text.color }; 
 <p :style="textColor">
 this.text.color = color;

7º DESAFIO

10. Componentes

  • Nesse tópico, vamos aprender sobre os componentes.

  • Componentes são blocos reusáveis de código que possuem estrutura e funcionalidade.

Objetivo

  • Vamos criar o componente meme-generator, para refatorar nosso código.

Vue CLI

  • Vue CLI é uma ferramenta para criar rapidamente aplicações Vue.js;
  • Possui um conjunto de configurações de build prontas para um processo de trabalho de front-end moderno;
  • Leva apenas alguns minutos para estar pronto e executando com hot-reload, lint ao salvar e empacotamente pronto para distribuição em produção. 

Vue CLI - Instalação

  npm install -g @vue/cli
  # OR
  yarn global add @vue/cli

Requisito - Node.js

Vue CLI exige Node.js na versão 8.9 ou acima (recomendado 8.11.0 +). Você pode gerenciar múltiplas versões do Node na mesma máquina usando o nvm ou nvm-windows.

Yarn - instalação ubuntu, instalação windows

Para instalar o Vue-CLI

Checar sua versão

 vue --version

Vue create project

Vue CLI
? Please pick a preset: (User arrow keys)
> default (babel, eslint)
  Manually select features
> vue create meme-generator

Vue create project

yarn serve

localhost:8080

Estrutura inicial

Problema

  • Em uma aplicação Vue, nós não queremos que todos nossos dados, métodos, dados computados, entre outros na raiz da instância Vue.
  • Inclusive, nós queremos deixar nosso código modular e mais fácil de trabalhar.

Estrutura

de um

Single File

Component

 
  <template>
    <div>
      <!-- html -->
    </div>
  </template>

  <script>
    export default {
      name: 'ComponentName',
      data() {
        return {
          // data
        };
      },
      methods: {
        // methods
      },
      ...
    };
  </script>

  <style>
    /* css */
  </style>

html

js

css

Single File Component

  <template>
    <p>{{ hello }}</p>
  </template>

  <script>
    export default {
      name: 'HelloWorld',
      
      data() {
        return {
          hello: 'Hello World!'
      }
    }
  }
  </script>

  <style scoped>
    p {
      color: blue;
    }
  </style>

hello-world.vue

<div id="app">
  <hello-world />
</div>

index.html

Solução

Vamos criar um componente chamado, meme-generator.vue dentro da pasta components

  • kebab-case.vue
  • CamelCase.vue

Nomenclatura de componentes

<template>
  <div class="row m-0 py-2 text-center">
    <!-- html content -->
  </div>
</template>

<script>

export default {
  name: 'MemeGenerator',

  data() {
    return {
      title: '',
       // data content
    };
  },

  computed: {},

  created() {},

  methods: {},
};

</script>

<style scoped>
/* style.css */
</style>

meme-generator/src/components/meme-generator.vue

meme-generator.vue

<template>
  <div id="app">
    <meme-generator />
  </div>
</template>

<script>

import MemeGenerator from './components/meme-generator';

export default {
  name: 'app',
  components: {
    MemeGenerator
  }
}
</script>

meme-generator/src/App.vue

Importar o componente

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <!-- Bootstrap 4 CSS -->
    <link rel="stylesheet" href="https://bootswatch.com/4/lux/bootstrap.min.css">
    <!-- Font -->
    <link href="https://fonts.googleapis.com/css?family=Passion+One&display=swap" rel="stylesheet">
    <title>Meme Generator</title>
  </head>
  <body>
    <noscript>
      <strong>
        We're sorry but meme-generator doesn't work properly without JavaScript enabled.
        Please enable it to continue.
      </strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

meme-generator/public/index.html

Incluir meta tags, bootstrap e fonte

It workss!!

10. Componentes

 

  • Componentes são blocos de código reusáveis;
  • Componentes facilitam a manutenção da aplicação.

( O que aprendemos)

11. Eventos customizados

Nesse tópico, vamos aprender a criar nossos eventos customizados.

Objetivo

Criar um componente chamado text-color.vue, e emitir um evento customizado para o componente pai (meme-generator) alterar a cor do texto.

Criar componente - text-color.vue

<template>
  <div class="form-group">
    <label>TEXT COLOR</label>
    <span
      v-for="(color, index) in colors"
      :key="index"
    >
      <span
        id="span-color"
        :style="{ background: color }"
      >
      </span>
    </span>
  </div>
</template>

<script>
export default {
  name: 'TextColor',
};
</script>

<style scoped>

#span-color {
  border: 1px solid #000;
  border-radius: 50%;
  cursor: pointer;
  display: inline-block;
  width: 16px;
  height: 16px;
  margin-left: 3px;
}

</style>

Importar o componente

  <text-color />

meme-generator.vue

<script>

import TextColor from './text-color.vue';

export default {
  name: 'MemeGenerator',
  
  components: {
    TextColor
  },
}

</script>

Property colors ir not defined

Componente (Props)

Propriedades são atributos customizados que você pode registrar em um componente

<script>
export default {
  name: 'TextColor',
  
  props: {
    colors: {
      type: Array,
      required: true
    },
  }
};
</script>

text-color.vue

  <text-color :colors="colors" />

meme-generator.vue

Propriedades do componente

  • Propriedades podem ter tipos, ser obrigatórias, e ter valores default.
props: {
  name: {
    type: String,
    required: true
  },
    
  age: {
    type: Number,
    required: true
  },
}
props: {
  url: {
    type: String,
    required: false,
    default() {
      return '/url';
    }
  },
    
  canEdit: {
    type: Boolean,
    required: false,
    default() {
      return false;
    }
  },
}

Problema

  • Como vou comunicar o componente pai, que preciso atualizar a cor do texto?

Solução

  • Criar um evento customizado, para enviar a cor do texto que o usuário clicou para o componente pai atualizar a cor do texto.

Eventos customizados

  this.$root.$emit('event-name');

Emitir um evento

Ouvir um evento

  this.$root.$on('event-name', (data) => {
    // do something;
    // this.method();
  });

source

source

Componente TextColor

<template>
  <div class="form-group">
    <label>TEXT COLOR</label>
    <span
      v-for="(color, index) in colors"
      :key="index"
    >
      <span
        id="span-color"
        :style="{ background: color }"
        @click="emitUpdateTextColor(color)"
      >
      </span>
    </span>
  </div>
</template>

<script>
export default {
  name: 'TextColor',

  props: {
    colors: {
      type: Array,
      required: true
    },
  },

  methods: {
    emitUpdateTextColor(color) {
      this.$root.$emit('update-text-color', color);
    },
  },
};
</script>

@click

method

Evento disparado

Componente Meme Generator

export default {
  ...,
  created() {
    this.setTitle();
    this.onUpdateTextColor();
  },
  
  methods: {
    onUpdateTextColor() {
      this.$root.$on('update-text-color', (color) => {
        this.updateTextColor(color);
      })
    },
    
    updateTextColor(color) {
      this.text.color = color;
    }
  }
}

11. Eventos customizados

 

  • Um componente pode emitir eventos com o $emit;
  • Um componente pode ouvir eventos com o $on;
  • Um componente pode emitir dados em conjunto com o evento $emit.

( O que aprendemos)

12. Desafios

 

  • Criar memes com o gerador de memes, e postar nos comentários abaixo!
  • Salvar imagem com print (linux: Fn + Shift + Prt Sc)

Desafio - nível VERY EASY

Desafio - nível VERY EASY

 

  • Adicionar um input que recebe a url da imagem, e atualiza a imagem na hora;

Desafio - nível EASY

 

  • Adicionar um input para alterar o tamanho da fonte dos textos, que recebe o valor da fonte. Ex: 30px, 50px, etc.

Desafio - nível EASY

 

  • Criar uma opção parecida com a TEXT COLOR para alterar a sombra da descrição do texto do meme, chamado TEXT SHADOW COLOR.

Desafio - nível EASY

 

  • Criar um checkbox com o texto UPPERCASE que quando for marcado alterar o :style do texto para letras maiúsculas e quando desmarcado alterar para letras minúsculas;

Desafio - nível MEDIUM

 

  • Criar um select para alterar o tipo de fonte utilizada no gerador de meme.

Desafio - nível MEDIUM

 

  • Criar um componente chamado MEME GALLERY, que contém uma galeria de memes, que quando clicado na imagem atualiza o meme atual.

Desafio - nível HARD

 

  • Adicionar um botão de DOWNLOAD que realiza o download da imagem do MEME.

Desafio - nível HARD

Referências

Cursos - Vue Mastery

Cursos - Vue School

Links úteis

Obrigado!

Introdução ao Vue.js

By Renan Gabriel

Introdução ao Vue.js

  • 763