Skip to content

josemalcher/CODE3R-Curso-VueJS-2-O-Guia-Completo-incl-Vue-Router-Vuex

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Curso Vue JS 2 - O Guia Completo (incl. Vue Router & Vuex)

https://www.udemy.com/course/vue-js-completo/

VueJS é um framework Javascript fantástico p construir aplicações Frontend! Vue.js mistura o melhor do Angular + React!

  1. Seção 01: Introdução
  2. Seção 02: Usando VueJS para Interagir com a DOM
  3. Seção 03: Usando Condicionais & Renderização de Listas
  4. Seção 04: Projeto #01 - O Matador de Monstros
  5. Seção 05: Entendendo a Instância Vue
  6. Seção 06: Fluxo de Desenvolvimento "Real" Usando Vue CLI
  7. Seção 07: Introdução aos Componentes
  8. Seção 08: Comunicação Entre Componentes
  9. Seção 09: Uso Avançado de Componentes
  10. Seção 10: Projeto #02 - Tarefas (TODO)
  11. Seção 11: Manipulando Entrada de Usuário com Formulários
  12. Seção 12: Usando e Criando Diretivas
  13. Seção 13: Melhorando sua App com Filtros e Mixins
  14. Seção 14: Adicionando Animações e Transições
  15. Seção 15: Conectando com Servidor via HTTP
  16. Seção 16: Rotas em uma Aplicação VueJS
  17. Seção 17: Melhor Gerenciamento de Estado com Vuex
  18. Seção 18: Projeto #03 - The Stock Trader
  19. Seção 19: Publicando uma Aplicação VueJS na Amazon
  20. Seção 20: Bonus: Projeto #04 - Projeto Calculadora
  21. Seção 21: Bonus: Projeto #05 - Problema Monty Hall
  22. Seção 22: Bonus: Projeto #06 - Base de Conhecimento Backend
  23. Seção 23: Bonus: Projeto #06 - Base de Conhecimento Frontend
  24. Seção 24: Bonus: CSS Grid & Flexbox
  25. Seção 25: Bonus: Javascript Essencial
  26. Seção 26: Bonus: HTML Essencial

  1. Introdução do Curso

  2. Vamos Criar Nossa Primeira APP em VueJS

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Primeira APP VUE</title>
</head>
<body>

<div id="app">
    <p>{{titulo}}</p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            titulo: 'Usando Vue JS 2 !'
        }
    });
</script>
</body>
</html>
  1. Extendendo Nossa Aplicação VueJS
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Primeira APP VUE</title>
</head>
<body>

<div id="app">
    <input type="text" v-on:input="alterarTitulo">
    <p>{{titulo}}</p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            titulo: 'Usando Vue JS 2 !'
        },
        methods: {
            alterarTitulo(event) {
                this.titulo = event.target.value
            }
        }
    });
</script>
</body>
</html>
  1. Executando o Código Localmente

  2. Mensagem do Maximilian Schwarzmüller

  3. Visão Geral do Curso

  4. Tire Proveito de Todos os Recursos do Curso!

  5. Atalhos no Visual Studio Code

  6. Recursos do Módulo & Links Úteis

  7. Usando o terminal

  8. Terminais

  1. Aviso importante aos usuários de Windows

Voltar ao Índice


  1. Introdução do Módulo

  2. Entendendo VueJS Templates

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Seção 2</title>
</head>
<body>

<div id="app">
    <p>{{titulo}}</p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            titulo: 'Usando Vue JS 2 !'
        }
    });
</script>
</body>
</html>
  1. Sintaxe de Template e Instância VueJS Trabalhando Juntos
<div id="app">
    <p>{{titulo}}</p>
    <p>{{saudacao()}}</p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            titulo: 'Usando Vue JS 2 !'
        }, methods: {
            saudacao: function (){
                return 'Boa Semana'; // sempre retorna string para o HTML
            }
        }
    });
</script>
  1. Acessando Dados na Instância VueJS
<div id="app">
  <p>{{titulo}}</p>
  <p>{{saudacao()}}</p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  new Vue({
    el: '#app',
    data: {
      titulo: 'Usando Vue JS 2 !'
    }, methods: {
      saudacao: function (){
        console.log(this)
        /* (...)
          saudacao: ƒ ()
          titulo: "Usando Vue JS 2 !"
        */
        return this.titulo;
      }
    }
  });
</script>
  1. Binding de Atributos
<div id="app">
  <p>{{titulo}}</p>
  <p>{{saudacao()}}</p>
  <a v-bind:href="link">Blog José Malcher Jr.</a>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  new Vue({
    el: '#app',
    data: {
      titulo: 'Usando Vue JS 2 !',
      link: 'https://josemalcher.net'
    }, methods: {
      saudacao: function (){
        return this.titulo;
      }
    }
  });
</script>
  1. Entendendo e Usando Diretivas

  2. Evitando Re-Renderização com v-once

<div id="app">
  <p v-once>{{titulo}}</p>
  <p>{{saudacao()}}</p>
  <a v-bind:href="link">Blog José Malcher Jr.</a>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  new Vue({
    el: '#app',
    data: {
      titulo: 'Titulo com V-Once',
      link: 'https://josemalcher.net'
    }, methods: {
      saudacao: function (){
        this.titulo = 'BOM DIA!!! (titulo alterado junto com saudação)'
        return this.titulo;
      }
    }
  });
</script>
  1. Como Imprimir HTML Puro
<div id="app">
  <p v-once>{{titulo}}</p>
  <p>{{saudacao()}}</p>
  <a v-bind:href="link">Blog José Malcher Jr.</a>

  <p v-html="linkHTML"></p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  new Vue({
    el: '#app',
    data: {
      titulo: 'Titulo com V-Once',
      link: 'https://josemalcher.net',
      linkHTML: '<a href="https://josemalcher.net">José Malcher Jr. Blog</a>'
    }, methods: {
      saudacao: function (){
        this.titulo = 'BOM DIA!!! (titulo alterado junto com saudação)'
        return this.titulo;
      }
    }
  });
</script>
  1. Hora de Praticar - Template
<script src="https://unpkg.com/vue"></script>

<div id="desafio">
    <!-- 1) Preencha a tag <p> abaixo com o seu Nome e Idade - usando Interpolação -->
    <p>Usando VueJS - SEU_NOME (IDADE)</p>
    
    <!-- 2) Exiba sua idade multiplicada por 3 -->
    <p></p>
    
    <!-- 3) Chame uma função para exibir um número randomico
        entre 0 and 1 (Math.random()) -->
    <p></p>
    
    <!-- 4) Procure uma imagem no google e exiba na tag img 
        fazendo o binding no atributo "src" -->
    <div>
        <img height="400">
    </div>
    
    <!-- 5) Inicialize o input com o seu nome (use o atributo "value") -->
    <div>
        <input type="text">
    </div>
</div>
<script src="app.js"></script>
  1. Hora de Praticar - Template (Resposta)
<script src="https://unpkg.com/vue"></script>

<div id="desafio">
    <!-- 1) Preencha a tag <p> abaixo com o seu Nome e Idade - usando Interpolação -->
    <p>Usando VueJS - {{nome}} ({{idade}})</p>

    <!-- 2) Exiba sua idade multiplicada por 3 -->
    <p>Mutaches {{ idade * 3 }} - Método {{ idadeVezesTres()}}</p>

    <!-- 3) Chame uma função para exibir um número randomico
        entre 0 and 1 (Math.random()) -->
    <p>{{ Math.random() }} - Método{{ random() }}</p>

    <!-- 4) Procure uma imagem no google e exiba na tag img
        fazendo o binding no atributo "src" -->
    <div>
        <img v-bind:src="image" height="200">
    </div>

    <!-- 5) Inicialize o input com o seu nome (use o atributo "value") -->
    <div>
        <input type="text" v-bind:value="nome">
    </div>
</div>
<script src="app.js"></script>
new Vue({
    el: '#desafio',
    data: {
        nome: 'José Malcher Jr.',
        idade: '36',
        image: 'https://pbs.twimg.com/profile_images/1106193889/logo_Super_A__o_Web_caixa_pequena_400x400.png'
    }, methods: {
        idadeVezesTres(){
            return this.idade * 3
        },
        random(){
            return Math.random();
        }
    }
});
  1. Escutando Eventos
<div id="app">
  <p>{{contador}}</p>
  <button v-on:click="somar">SOMAR 1</button>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  new Vue({
    el: '#app',
    data: {
      contador: 0
    },
    methods: {
      somar(){
        this.contador++
      }
    }
  });
</script>
  1. Obtendo Dados do Evento
<div id="app">
    <p>{{contador}}</p>
    <button v-on:click="somar">SOMAR 1</button>
    <p v-on:mouseover="atualizaXY">Mouse: {{ x }} - {{ y }}</p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            contador: 0,
            x: 0,
            y: 0
        },
        methods: {
            somar(){
                this.contador++
            },
            atualizaXY(event){
                this.x = event.clientX
                this.y = event.clientY
            }

        }
    });
</script>
  1. Passando nosso próprios Argumentos com Eventos
<div id="app">
  <p>{{contador}}</p>
  <button v-on:click="somar(5, $event)">SOMAR 1</button>
  <p v-on:mouseover="atualizaXY">Mouse: {{ x }} - {{ y }}</p>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  new Vue({
    el: '#app',
    data: {
      contador: 0,
      x: 0,
      y: 0
    },
    methods: {
      somar(passo, ev){
        console.log(passo, ev) // 5 MouseEvent {isTrusted: true, screenX: 1446, screenY: -942, (...)
        this.contador += passo
      },
      atualizaXY(event){
        this.x = event.clientX
        this.y = event.clientY
      }

    }
  });
</script>
  1. Modificadores de Eventos
<div id="app">
    <p>{{contador}}</p>
    <button v-on:click="somar(5, $event)">SOMAR 1</button>
    <p v-on:mouseover="atualizaXY">Mouse: {{ x }} - {{ y }}
        <span v-on:mousemove.stop.prevent>PARAR EFEITO AQUI!</span>
    </p>
    <a v-on:click="naoNavegar" href="https://google.com">GOOGLE</a>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            contador: 0,
            x: 0,
            y: 0
        },
        methods: {
            somar(passo, ev) {
                console.log(passo, ev) // 5 MouseEvent {isTrusted: true, screenX: 1446, screenY: -942, (...)
                this.contador += passo
            },
            atualizaXY(event) {
                this.x = event.clientX
                this.y = event.clientY
            },
            naoNavegar(event) {
                console.log('Não Navegar aqui')
                event.preventDefault()
            },
            parar(event) {
                event.stopPropagation()
            }

        }
    });
</script>
  1. Eventos de Teclado

-https://vuejs.org/v2/guide/events.html#Key-Modifiers

<div id="app">
<p>{{contador}}</p>
<button v-on:click="somar(5, $event)">SOMAR 1</button>
<p v-on:mouseover="atualizaXY">Mouse: {{ x }} - {{ y }}
  <span v-on:mousemove.stop.prevent>PARAR EFEITO AQUI!</span>
</p>
<a v-on:click="naoNavegar" href="https://google.com">GOOGLE</a>

<input type="text" v-on:keyup.enter.alt="exibirAlerta">
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
new Vue({
  el: '#app',
  data: {
    contador: 0,
    x: 0,
    y: 0
  },
  methods: {
    somar(passo, ev) {
      console.log(passo, ev) // 5 MouseEvent {isTrusted: true, screenX: 1446, screenY: -942, (...)
      this.contador += passo
    },
    atualizaXY(event) {
      this.x = event.clientX
      this.y = event.clientY
    },
    naoNavegar(event) {
      console.log('Não Navegar aqui')
      event.preventDefault()
    },
    exibirAlerta(){
      console.log('ENTROU COM ENTER + ALT')
    },
    parar(event) {
      event.stopPropagation()
    }

  }
});
</script>
  1. Hora de Praticar - Eventos
<script src="https://unpkg.com/vue"></script>

<div id="desafio">
    <!-- 1) Exiba um alert quando o botão for clicado -->
    <div>
        <button>Exibir Alerta</button>
    </div>
    
    <!-- 2) Escute o evento "keydown" e armazene o valor na propriedade
        data (dica: event.target.value) -->
    <div>
        <input type="text">
        <p>{{ valor }}</p>
    </div>
    
    <!-- 3) Ajuste o exemplo 2 para disparar o evento "keydown" somente
        quando a tecla for ENTER -->
    <div>
        <input type="text">
        <p>{{ valor }}</p>
    </div>
</div>
<script src="app.js"></script>
  1. Hora de Praticar - Eventos (Resposta)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script src="https://unpkg.com/vue"></script>

<div id="desafio">
    <!-- 1) Exiba um alert quando o botão for clicado -->
    <div>
        <button v-on:click="exibirAlerta">Exibir Alerta</button>
    </div>

    <!-- 2) Escute o evento "keyup" e armazene o valor na propriedade
        data (dica: event.target.value) -->
    <div>
        <input type="text" v-on:keyup="valor = $event.target.value">
        <p>{{ valor }}</p>
    </div>

    <!-- 3) Ajuste o exemplo 2 para disparar o evento "keydown" somente
        quando a tecla for ENTER -->
    <div>
        <input type="text" v-on:keydown.enter="valor = $event.target.value">
        <input type="text" v-on:keydown.enter="alterarValor">
        <p>{{ valor }}</p>
    </div>
</div>
<script src="app.js"></script>
</body>
</html>
new Vue({
    el: '#desafio',
    data: {
        valor: ''
    },
    methods: {
        exibirAlerta() {
            alert('Estou Alertando AGORA!!');
        },
        alterarValor(event) {
            this.valor = event.target.value;
        }
    }
})
  1. Código JavaScript no Template
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Seção 2</title>
</head>
<body>

<div id="app">
    <p>{{contador}}</p>
    <p>{{contador > 10 ? 'MAIOR que 10' : 'Menor que 10'}}</p>
    <button v-on:click="somar(5, $event)">SOMAR 1</button>
</div>

<script src="https://unpkg.com/vue"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            contador: 0,
        },
        methods: {
            somar() {
                this.contador++
            }
        }
    });
</script>
</body>
</html>
  1. Usando Two-Way-Binding
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Seção 2</title>
</head>
<body>

<div id="app">
    <p>{{titulo}}</p>
    <input type="text" v-model="titulo">
</div>

<script src="https://unpkg.com/vue"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            titulo: 'Título Principal',
        }
    });
</script>
</body>
</html>
  1. Propriedades Computadas
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Seção 2</title>
</head>
<body>

<div id="app">
    <button v-on:click="aumentar">Aumentar</button>
    <button v-on:click="contador2++">Aumentar 2</button>
    <button v-on:click="diminur">Diminuir</button>
    <p>Contador: {{ contador }} | {{ contador2}}</p>
    <p>Resultado: {{ resultado }}</p>
</div>

<script src="https://unpkg.com/vue"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            contador: 0,
            contador2: 0,
        },
        computed: {
            resultado() {
                console.log('Método computed resultado chamado....')
                return this.contador >= 5 ? 'MAIOR ou IGUAL a 5' : 'Menor que 5'
            }
        },
        methods: {
            aumentar() {
                this.contador++

            },
            diminur() {
                this.contador--
            }
        }
    });
</script>
</body>
</html>
  1. Monitorando as Mudanças
<div id="app">
    <button v-on:click="aumentar">Aumentar</button>
    <button v-on:click="contador2++">Aumentar 2</button>
    <button v-on:click="diminur">Diminuir</button>
    <p>Contador: {{ contador }} | {{ contador2}}</p>
    <p>Resultado: {{ resultado }}</p>
</div>

<script src="https://unpkg.com/vue"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            contador: 0,
            contador2: 0,
        },
        computed: {
            resultado() {
                console.log('Método computed resultado chamado....')
                return this.contador >= 5 ? 'MAIOR ou IGUAL a 5' : 'Menor que 5'
            }
        },
        watch: {
            contador(){ // mesmo nome da propriedade
                setTimeout(() => {
                    this.contador = 0;
                }, 2000)
            }
        },

        methods: {
            aumentar() {
                this.contador++

            },
            diminur() {
                this.contador--
            }
        }
    });
</script>
  1. Sintaxe Reduzida (Shorthands)
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Seção 2</title>
</head>
<body>

<div id="app">
  <p>{{contador}}</p>
  <button @click="somar">SOMAR 1</button>
  <input type="text" :value="contador">
</div>

<script src="https://unpkg.com/vue"></script>
<script>
  new Vue({
    el: '#app',
    data: {
      contador: 0
    },
    methods: {
      somar(){
        this.contador++
      }
    }
  });
</script>
</body>
</html>
  1. Hora de Praticar - Propriedades Reativas
<script src="https://unpkg.com/vue"></script>

<div id="desafio">
    <!-- 1) Exibir em "resultado" o texto 'Valor Diferente' enquanto
        "valor" for diferente de 37 - "valor" é alterado pelos botões.
        Mostrar 'Valor Igual' quando "valor" for igual a 37 -->
        
    <!-- 2) Monitorar as mudança de "resultado" e reiniciar "valor"
        para 0 depois de 5 segundos (dica: setTimeout(..., 5000) -->            
    <div>
        <p>Valor atual: {{ valor }}</p>
        <button @click="valor += 5">Somar 5</button>
        <button @click="valor += 1">Somar 1</button>
        <p>{{ resultado }}</p>
    </div>

</div>
<script src="app.js"></script>
  1. Hora de Praticar - Propriedades Reativas (Resposta)
new Vue({
    el: '#desafio',
    data: {
        valor: 0
    },
    computed:{
        resultado(){
            return this.valor == 37 ? 'Valor Igual' : 'Valor diferente';
        }
    },
    watch: {
        resultado(){
            setTimeout(()=>{
                this.valor = 0
            }, 5000)
        }
    }
});
  1. Estilo Dinâmico e Classe CSS #01
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Seção 2</title>
</head>
<style>
    #app {
        display: flex;
        justify-content: space-around;
    }

    .demo {
        width: 100px;
        height: 100px;
        background: gray;
    }

    .c1 {
        background-color: red;
    }

    .c2 {
        background-color: black;
    }

    .c3 {
        background-color: blue
    }
</style>
<body>

<div id="app">
    <div class="demo" :class="{c1:aplicarC1}" @click="aplicarC1 = !aplicarC1"></div>
    <div class="demo"></div>
    <div class="demo"></div>
</div>

<script src="https://unpkg.com/vue"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            aplicarC1: false
        }

    });
</script>
</body>
</html>
  1. Estilo Dinâmico e Classe CSS #02
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Seção 2</title>
</head>
<style>
  #app {
    display: flex;
    justify-content: space-around;
  }

  .demo {
    width: 100px;
    height: 100px;
    background: gray;
  }

  .c1 {
    background-color: red;
  }

  .c2 {
    background-color: green;
  }

  .c3 {
    background-color: blue
  }
</style>
<body>

<div id="app">
  <div class="demo" :class="estilo1"
       @click="aplicarC1 = !aplicarC1"></div>
  <div class="demo"></div>
  <div class="demo"></div>
</div>

<script src="https://unpkg.com/vue"></script>
<script>
  new Vue({
    el: '#app',
    data: {
      aplicarC1: false
    },
    computed:{
      estilo1(){
        return {
          c1: this.aplicarC1,
          c2: !this.aplicarC1
        }
      }
    }

  });
</script>
</body>
</html>
  1. Estilo Dinâmico e Classe CSS #03
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Seção 2</title>
</head>
<style>
    .caixas {
        display: flex;
        justify-content: space-around;
    }

    .demo {
        width: 100px;
        height: 100px;
        background: gray;
    }

    .c1 {
        background-color: red;
    }

    .c2 {
        background-color: green;
    }

    .c3 {
        background-color: blue
    }
    .girar{
        transform: rotate(45deg);
    }
</style>
<body>

<div id="app">
    <div class="caixas">
        <div class="demo" :class="estilo1"
             @click="aplicarC1 = !aplicarC1"></div>
        <div class="demo" :class="estilo1"></div>
        <div class="demo" :class="[classCSS, {girar: aplicarGirar }]"></div>
    </div>
    <hr>
    <input type="text" v-model="classCSS">
</div>

<script src="https://unpkg.com/vue"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            aplicarC1: false,
            classCSS: 'c1',
            aplicarGirar: true

        },
        computed: {
            estilo1() {
                return {
                    c1: this.aplicarC1,
                    c2: !this.aplicarC1
                }
            }
        }

    });
</script>
</body>
</html>
  1. Estilo Dinâmico Sem Classes CSS
<div id="app">
    <div class="caixas">
        <div class="demo" :style="{backgroundColor: cor}"></div>
        <div class="demo" :style="[meuEstilo, {height: altura}]"></div>
        <div class="demo"></div>
    </div>
    <hr>
    <input type="text" v-model="cor">
    <input type="text" v-model="largura">
</div>

<script src="https://unpkg.com/vue"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            cor: 'red',
            largura: 100,
            altura: 50
        },
        computed: {
            meuEstilo(){
                return{
                    backgroundColor: this.cor,
                    width: this.largura + 'px'
                }
            }
        }

    });
</script>
  1. Hora de Praticar: Estilo
<link rel="stylesheet" href="styles.css">
<script src="https://unpkg.com/vue"></script>

<div id="desafio">
	<!-- 1) Iniciar a execução do efeito usando botão. 
    O efeito deve alternadamente trocar as classes "destaque" e
    "encolher" para cada chamada de setInteval. Use a div abaixo
	com id "efeito" para associar as classes CSS. -->
	<h2>#01</h2>
	<div>
		<button @click="iniciarEfeito">Iniciar Efeito</button>
		<div id="efeito"></div>
	</div>
	
	<!-- 2) Crie duas classes CSS e associe a div usando a
		sintaxe de array -->
	<h2>#02</h2>
	<div>Estou sem classe CSS :(</div>

	<!-- 3) Aplique na div abaixo a classe informada pelo usuário
		(crie classe CSS de exemplo). -->
	<h2>#03</h2>
	<div>
		<input type="text">
		<div></div>
	</div>

	<!-- 4) Aplique na div abaixo a classe informada pelo usuário e
    outra classe usando o valor true/false (crie classes CSS de exemplo). -->
	<h2>#04</h2>
	<div>
		<input type="text">
		<input type="text">
		<div></div>
	</div>

	<!-- 5) Repita 3) mas utilizando estilos ao invés de classes CSS.
    Associe os estilos a div abaixo  -->
	<h2>#05</h2>
	<div>
		<input type="text">
		<div></div>
	</div>

	<!-- 6) Crie uma barra de progresso simples com setInterval 
    e binding de estilo. -->
	<h2>#06</h2>
	<div>
		<button @click="iniciarProgresso">Iniciar</button>
		<div></div>
	</div>
</div>
<script src="app.js"></script>
  1. Hora de Praticar: Estilo (Resposta)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<link rel="stylesheet" href="style.css">
<script src="https://unpkg.com/vue"></script>

<div id="desafio">
  <!-- 1) Iniciar a execução do efeito usando botão.
  O efeito deve alternadamente trocar as classes "destaque" e
  "encolher" para cada chamada de setInteval. Use a div abaixo
  com id "efeito" para associar as classes CSS. -->
  <h2>#01</h2>
  <div>
    <button @click="iniciarEfeito">Iniciar Efeito</button>
    <div id="efeito" :class="classe1"></div>
  </div>

  <!-- 2) Crie duas classes CSS e associe a div usando a
      sintaxe de array -->
  <h2>#02</h2>
  <div :class="[{perigo}, 'quadrado']">Estou sem classe CSS :(</div>

  <!-- 3) Aplique na div abaixo a classe informada pelo usuário
      (crie classe CSS de exemplo). -->
  <h2>#03</h2>
  <div>
    <input type="text" v-model="classe3">
    <div :class="classe3"></div>
  </div>

  <!-- 4) Aplique na div abaixo a classe informada pelo usuário e
  outra classe usando o valor true/false (crie classes CSS de exemplo). -->
  <h2>#04</h2>
  <div>
    <input type="text" v-model="classe4">
    <input type="text" @input="setPerigo">
    <div :class="[classe4, {perigo}]"></div>
  </div>

  <!-- 5) Repita 3) mas utilizando estilos ao invés de classes CSS.
  Associe os estilos a div abaixo  -->
  <h2>#05</h2>
  <div>
    <input type="text" v-model="cor5">
    <div :style="[estilo5, {backgroundColor: cor5}]"></div>
  </div>

  <!-- 6) Crie uma barra de progresso simples com setInterval
  e binding de estilo. -->
  <h2>#06</h2>
  <div>
    <button @click="iniciarProgresso">Iniciar</button>
    <div class="barra-progresso">
      <div class="progresso" :style="{width}"></div>
    </div>
  </div>
</div>
<script src="app.js"></script>
</body>
</html>
new Vue({
    el: '#desafio',
    data: {
        classe1: 'destaque',
        perigo: true,
        classe3: '',
        classe4: '',
        cor5: '',
        estilo5: {
            width: '100px',
            height: '100px',
        },
        width: '0',
    },
    methods: {
        iniciarEfeito() {
            setInterval(() => {
                this.classe1 = this.classe1 == 'destaque'
                    ? 'encolher' : 'destaque'
            }, 1000)
        },
        iniciarProgresso() {
            let valor = 0
            const temporizador = setInterval(() => {
                valor += 5
                this.width = `${valor}%`
                if(valor == 100) clearInterval(temporizador)
            }, 500)
        },
        setPerigo(event) {
            if(event.target.value == "true") {
                this.perigo = true
            } else if(event.target.value == "false") {
                this.perigo = false
            }
        }
    }
})
  1. Conclusão do Módulo

  2. Recursos do Módulo & Links Úteis

Links Úteis:

Documentação Oficial - Introdução: https://br.vuejs.org/v2/guide/

Documentação Oficial - Sintaxe de Template: https://br.vuejs.org/v2/guide/syntax.html

Documentação Oficial - Manipulação de Eventos: https://br.vuejs.org/v2/guide/events.html

Documentação Oficial - Dados Computados & Observadores: https://br.vuejs.org/v2/guide/computed.html

Documentação Oficial - Interligações de Classe e Estilo: https://br.vuejs.org/v2/guide/class-and-style.html

Voltar ao Índice


  1. Introdução do Módulo

  2. Renderização Condicional com v-if/v-else

<div id="app">
    <p v-if="logado">Usuário Logado: {{ nome }}</p>
    <p v-else>Nenhum usuário logado</p>
    <button @click="logado = !logado">{{ logado ? 'Sair' : 'Entrar'}}</button>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            nome: 'José',
            logado: false
        }
    });
</script>
  1. Seleção Múltipla com v-else-if
<div id="app">
  <p v-if="logado">Usuário Logado: {{ nome }}</p>
  <p v-else-if="anonimo">Navegando como ANÔNIMO</p>
  <p v-else>Nenhum usuário logado</p>
  <button @click="logado = !logado">{{ logado ? 'Sair' : 'Entrar'}}</button>
  <input type="checkbox" v-model="anonimo">
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  new Vue({
    el: '#app',
    data: {
      nome: 'José',
      logado: false,
      anonimo: true
    }
  });
</script>
  1. Usando v-if com Template
<div id="app">
    <template v-if="logado">
        <p>Usuário Logado: {{ nome }}</p>
        <p>Perfil: Admin</p>
    </template>
    <p v-else-if="anonimo">Navegando como ANÔNIMO</p>
    <p v-else>Nenhum usuário logado</p>
    <button @click="logado = !logado">{{ logado ? 'Sair' : 'Entrar'}}</button>
    <input type="checkbox" v-model="anonimo">
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            nome: 'José',
            logado: false,
            anonimo: true
        }
    });
</script>
  1. Esconda o Elemento com v-show
<div id="app">
    <template v-if="logado">
        <p>Usuário Logado: {{ nome }}</p>
        <p>Perfil: Admin</p>
    </template>
    <p v-else-if="anonimo">Navegando como ANÔNIMO</p>
    <p v-else>Nenhum usuário logado</p>
    <button @click="logado = !logado">{{ logado ? 'Sair' : 'Entrar'}}</button>
    <input type="checkbox" v-model="anonimo">
    <hr>
    <footer v-show="logado">Desenvolvido para você - admin!</footer>
    <footer v-show="!logado">Desenvolvido para você - DESCONHECIDO!!!</footer>

</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            nome: 'José',
            logado: false,
            anonimo: false
        }
    });
</script>
  1. Renderizando Lista com v-for
<div id="app">
  <ul>
    <li v-for="cor in cores"> {{ cor }}</li>
  </ul>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  new Vue({
    el: '#app',
    data: {
      cores: ['vermelho', 'verde', 'amarelo', 'azul'],
      pessoas: [
        {nome: 'Jose', idade: 36, peso: 90},
        {nome: 'Luciana', idade: 34, peso: 70},
      ]
    }
  });
</script>
  1. Acessando o Índice Atual
<div id="app">
    <ul>
        <li v-for="(cor, i) in cores"> {{ i + 1 }} -  {{ cor }}</li>
    </ul>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            cores: ['vermelho', 'verde', 'amarelo', 'azul'],
            pessoas: [
                {nome: 'Jose', idade: 36, peso: 90},
                {nome: 'Luciana', idade: 34, peso: 70},
            ]
        }
    });
</script>
  1. Usando v-for com Template
<div id="app">
    <ul>
        <li v-for="(cor, i) in cores"> {{ i + 1 }} -  {{ cor }}</li>
    </ul>
    <hr>
    <template v-for="(cor, i) in cores">
        <h2>{{ cor }}</h2>
        <p>{{ i + 1 }}</p>
    </template>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            cores: ['vermelho', 'verde', 'amarelo', 'azul'],
            pessoas: [
                {nome: 'Jose', idade: 36, peso: 90},
                {nome: 'Luciana', idade: 34, peso: 70},
            ]
        }
    });
</script>
  1. Iterando em Objetos
<div id="app">
  <ul>
    <li v-for="(cor, i) in cores"> {{ i + 1 }} -  {{ cor }}</li>
  </ul>
  <hr>
  <template v-for="(cor, i) in cores">
    <h2>{{ cor }}</h2>
    <p>{{ i + 1 }}</p>
  </template>

  <ul>
    <li v-for="pessoa in pessoas">
        <div v-for="(valor, chave, index) in pessoa">
          ({{ index + 1}}) - {{ chave }} = {{ valor }}
        </div>
    </li>
  </ul>

</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
  new Vue({
    el: '#app',
    data: {
      cores: ['vermelho', 'verde', 'amarelo', 'azul'],
      pessoas: [
        {nome: 'Jose', idade: 36, peso: 90},
        {nome: 'Luciana', idade: 34, peso: 70},
      ]
    }
  });
</script>
  1. Iterando em uma Lista de Números
<div id="app">
   <div v-for="n in 10">{{ n }}</div>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            cores: ['vermelho', 'verde', 'amarelo', 'azul'],
            pessoas: [
                {nome: 'Jose', idade: 36, peso: 90},
                {nome: 'Luciana', idade: 34, peso: 70},
            ]
        }
    });
</script>
  1. Identificando os Elementos no v-for
<div id="app">
    <div v-for="(cor, i) in cores" :key="i">{{ i }} - {{ cor }}</div> <!-- No video usar "cor" - preferir usar o "i"-->
    <button @click="cores.push('branco')">Adicionar Cor Branca</button>
    <button @click="cores.push('Vermelho')">Adicionar Cor Vermelho</button>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            cores: ['vermelho', 'verde', 'amarelo', 'azul'],
            pessoas: [
                {nome: 'Jose', idade: 36, peso: 90},
                {nome: 'Luciana', idade: 34, peso: 70},
            ]
        }
    });
</script>
  1. Hora de Praticar: Condicionais & Listas

  2. Hora de Praticar: Condicionais & Listas (Resposta)

<!DOCTYPE html>
<html lang="pt-br">
<head>
  <meta charset="UTF-8">
  <title>Seção 3</title>
</head>
<body>

<div id="desafio">
  <!-- 1) Ligue o botão para alternar a exibição dos dois
    parágrafos. Use ambos v-if e v-show e inspecione os elementos
    para ver a diferença -->
  <h2>#01</h2>
  <div>
    <button @click="expressao = !expressao">Alternar</button>
    <p v-if="expressao">Você quer me ver ...</p>
    <p v-else="expressao">...ou eu</p>
    <p v-show="expressao">Você quer me ver ...</p>
    <p v-show="!expressao">...ou eu</p>
  </div>

  <!-- 2) Exiba em uma <ul> um array de elementos da sua escolha.
    Imprima também o índice de cada elemento. -->
  <h2>#02</h2>
  <ul>
    <li v-for="(nome, i) in nomes">{{ i }} - {{ nome }}</li>
  </ul>

  <!-- 3) Imprimir todos os pares de valor-chave do objeto a seguir:
    {
			titulo: 'O Senhor dos Anéis',
			autor: 'J.R.R. Tolkiens',
			volume: '3'
		}
    Imprima também o índice de cada item. -->
  <h2>#03</h2>
  <ul>
    <li v-for="(valor, chave, index) in livro">
      {{chave}}: {{ valor }} {{index + 1}}
    </li>
  </ul>

  <!-- 4) Imprima o seguinte objeto (somente os valores) e
    também crie um loop aninhado para o array:
    {
			id: 10,
			nome: 'Maria',
			notas: [7.67, 8.33, 6.98, 9.21]
		}
    (dica: use v-for e v-if na resolução) -->
  <h2>#04</h2>
  <ul>
    <li v-for="valor in aluno">
      <template v-if="!Array.isArray(valor)">
        {{valor}}
      </template>
      <template v-else="Array.isArray(valor)">
      Notas:
        <ul><li v-for="notas in valor">{{notas}}</li></ul>
      </template>
    </li>
  </ul>
</div>


<script src="https://unpkg.com/vue"></script>
<script src="app.js"></script>
</body>
</html>



new Vue({
    el: '#desafio',
    data: {
        expressao: true,
        array: ['Pedro', 'Bia', 'Ana', 'Rebeca'],
        livro: {
            titulo: 'O Senhor dos Anéis',
            autor: 'J.R.R. Tolkiens',
            volume: '3'
        },
        aluno: {
            id: 10,
            nome: 'Maria',
            notas: [7.67, 8.33, 6.98, 9.21]
        },
        nomes: ['jose', 'luciana', 'marcus']
    }
});
  1. Conclusão do Módulo

  2. Recursos do Módulo & Links Úteis

Links Úteis:

Documentação Oficial - Renderização Condicional: https://br.vuejs.org/v2/guide/conditional.html

Documentação Oficial - Renderização de Listas: https://br.vuejs.org/v2/guide/list.html

Voltar ao Índice


Voltar ao Índice


  1. Introdução do Módulo

  2. Noções básicas sobre a Instância Vue

  3. Usando Múltiplas Instâncias Vue

<div id="app1">
  <p>{{titulo_1}}</p>
  <button @click="alterar">Alterar</button>
</div>

<div id="app2">
  <p>{{titulo_2}}</p>
  <button @click="alterar">Alterar</button>
</div>

<script src="../lib/vue.js"></script>
<script>
  new Vue({
    el: '#app1',
    data: {
      titulo_1: 'Usando Vue JS 2 !'
    },
    methods: {
      alterar(){
        this.titulo_1 += '!!!' ;
      }
    }
  });

  new Vue({
    el: '#app2',
    data: {
      titulo_2: 'Usando Vue JS 2 !'
    },
    methods: {
      alterar(){
        this.titulo_2 += '!?!?!?!' ;
      }
    }
  });
</script>
  1. Acessando a Instância Vue Externamente
<div id="app1">
  <p>{{titulo_1}}</p>
  <button @click="alterar">Alterar</button>
</div>

<div id="app2">
  <p>{{titulo_2}}</p>
  <button @click="alterar">Alterar</button>
</div>

<script src="../lib/vue.js"></script>
<script>
  const vm1 = new Vue({
    el: '#app1',
    data: {
      titulo_1: 'Usando Vue JS 2 !'
    },
    methods: {
      alterar(){
        vm2.titulo_2 += '!!!' ;
      }
    }
  });

  const vm2 = new Vue({
    el: '#app2',
    data: {
      titulo_2: 'Usando Vue JS 2 !'
    },
    methods: {
      alterar(){
        vm1.titulo_1 += '!?!?!?!' ;
      }
    }
  });

  setTimeout(() => {
    vm1.titulo_1 = 'Alterado Pelo TIMER!';
  }, 2000)

</script>
  1. Como o VueJS Gerencia os Dados e Métodos

  2. Meu Vue Framework

<div id="app">
  {{ nome }} {{ sobrenome }} {{ 100 - 55 }} {{ Math.pow(2, 3) }}
</div>

<!--<script src="../lib/vue.js"></script>-->

<script>
  function MeuVue(params) {
    this.$el = document.querySelector(params.el)
    this.$data = params.data

    for(let atr in this.$data) {
      Object.defineProperty(this, atr, {
        get: () => {
          return this.$data[atr]
        },
        set: value => {
          this.$data[atr] = value
        }
      })
    }

    // interpolar
    const regex = /\{\{([\s\w)(,.+*-]*)\}\}/g
    this.$el.innerHTML = this.$el.innerHTML.replace(regex, (match, $1) => {
      const value = this[$1.trim()]
      return value ? value : eval($1)
    })
  }

  const vm = new MeuVue({
    el: '#app',
    data: {
      nome: 'Maria',
      sobrenome: 'Silva'
    }
  })

  console.log(vm.nome)
  console.log(vm.$data.nome)

  vm.nome = 'Pedro'
  console.log(vm.nome)
  console.log(vm.$data.nome)

  // vm.$data.idade = 31
  // console.log(vm.idade)
</script>
  1. Uma Análise Mais Detalhada de $el e $data

  2. Colocando $refs e Usando nos Templates

<div id="app">
    <h1 ref="aulaRef">{{ aula }}</h1>
    <button @click="alterarAula">Alterar AULA</button>

    <h2>{{ modulo }}</h2>
    <button @click="alterarModulo">Alterar MODULO</button>
</div>

<script src="../lib/vue.js"></script>
<script>
    const vm = new Vue({
        el: '#app',
        data: {
            aula: 'AULA',
            modulo: 'MODULO',
        },
        methods: {
            alterarAula() {
                this.aula += '!!!';
            },
            alterarModulo() {
                this.modulo += '###';
                console.log(this.$refs.aulaRef.innerHTML);
            }
        }
    });

    vm.$refs.aulaRef.innerText = "ALTERADO DIRETAMENTE"
    console.log(vm.$refs)
    /*
    {aulaRef: h1}aulaRef: h1__proto__: Object
     vue.js:9064 You are running Vue 
    * */

</script>
  1. Onde Aprender Mais sobre a API do Vue

  2. Montando um Template

<div id="app">

</div>
<script src="../lib/vue.js"></script>
<script>
    const vm = new Vue({
        /*el: '#app',*/
        template: `
              <div>
                  <h1>{{ aula }}</h1>
                  <button @click="alterarAula">Alterar AULA</button>
                  <h2>{{ modulo }}</h2>
                  <button @click="alterarModulo">Alterar MODULO</button>
              </div>
        `,
        data: {
            aula  : 'AULA',
            modulo: 'MODULO',
        },
        methods: {
            alterarAula() {
                this.aula += '!!!';
            },
            alterarModulo() {
                this.modulo += '###';
            }
        }
    });

    //vm.$mount('#app');
    vm.$mount()
    document.querySelector('#app').appendChild(vm.$el)

</script>
  1. Usando Componentes
<div id="app">
    <comp></comp>
    <comp></comp>

</div>

<script src="../lib/vue.js"></script>
<script>
    Vue.component('comp', {
        template: `
              <div>
                  <h1>{{ aula }}</h1>
                  <button @click="alterarAula">Alterar AULA</button>
                  <h2>{{ modulo }}</h2>
                  <button @click="alterarModulo">Alterar MODULO</button>
              </div>
        `,
        data: function (){
            return {
                aula  : 'AULA',
                modulo: 'MODULO',
            }
        },
        methods: {
            alterarAula() {
                this.aula += '!!!';
            },
            alterarModulo() {
                this.modulo += '###';
            }
        }
    })


    const vm = new Vue({
        el: '#app',
    });

</script>
  1. Limitações dos Templates

  2. Como o VueJS Atualiza o DOM

  3. O Ciclo de Vida da Instância Vue #01

  4. O Ciclo de Vida da Instância Vue #02

<div id="app">
    <h1>{{ titulo }}</h1>
    <button @click="titulo += '#'">Alterar Título</button>
    <button @click="$destroy()">Destruir</button>
</div>
<script src="../lib/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            titulo: 'Ciclo de Vida'
        },
        beforeCreate() {
            console.log('Antes de Criar')
        },
        created() {
            console.log('Criado')
        },
        beforeMount() {
            console.log('Antes de Montar (DOM)')
        },
        mounted() {
            console.log('DOM Montada')
        },
        beforeUpdate() {
            console.log('Antes de Atualizar')
        },
        updated() {
            console.log('Atualizado')
        },
        beforeDestroy() {
            console.log('Antes de destruir')
        },
        destroyed() {
            console.log('Destruido')
        }
    })
</script>
  1. Conclusão do Módulo

  2. Recursos do Módulo & Links Úteis

Voltar ao Índice


  1. Introdução do Módulo

  2. Por que Precisamos de um Servidor Web?

  3. O que "Fluxo de Desenvolvimento" Significa?

  4. Usando o Vue CLI para Criar Projetos

  5. Instalando o Vue CLI e Criando um Novo Projeto

  6. Uma Visão Geral sobre a Estrutura de Pastas

  7. Entendendo os Arquivos ".vue"

  8. Como Construir sua APP para Produção

  9. Criando um Projeto e Salvando Template

  10. Adicionando Plugins ao Projeto

vue add vuetify
vue add electron-builder
  1. Conclusão do Módulo

  2. Mais sobre Arquivos ".vue" e o CLI

O Arquivo ".vue"

Você pode aprender mais sobre o arquivo ".vue" nesse artigo da documentação oficial: https://br.vuejs.org/v2/guide/single-file-components.html

Você pode aprender mais sobre o método  render()  nesse outro artigo na documentação oficial: https://br.vuejs.org/v2/guide/render-function.html

The CLI

Aprenda mais sobre o Vue CLI aqui: https://cli.vuejs.org/
  1. Depurando Projetos VueJS
Duas ferramentas que você pode usar:

1) Ferramenta de Desenvolvimento Vue (https://github.com/vuejs/vue-devtools)

2) A ferramenta de Desenvolvedor do Chrome

Quando estiver trabalhando com projetos criados com o CLI , você pode facilmente debugar a sua aplicação abrindo o a ferramenta de desenvolvimento (abaixo exemplo no Chrome) abrir a aba sources. Você deverá ver a pasta webpack:// e dentro você encontrará todos os arquivos do projeto (área em destaque vermelha).

Agora é só abrir os arquivos e colocar os breakpoints para debugar a sua aplicação em execução.
  1. Recursos do Módulo & Links Úteis

Voltar ao Índice


  1. Introdução do Módulo

  2. Revisão Sobre Componentes

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Seção 07</title>
</head>
<body>

<div id="app">
<contador></contador>
<contador></contador>
<contador></contador>
</div>

<script src="../lib/vue.js"></script>
<script>

    Vue.component('contador', {
        template: `
          <div>
          <span>{{contador}}</span>
          <button @click="contador++"> + </button>
          <button @click="contador--"> - </button>
          </div>
        `,
        data(){
            return {
                contador: 0
            }
        }
    });


    new Vue({
        el: '#app',
    });
</script>
</body>
</html>
  1. Registrar Componentes (Global e Local)
<div id="app1">
    <contador1></contador1>
    <contador1></contador1>
    <contador1></contador1>
</div>
<hr>
<div id="app2">
    <contador2></contador2>
    <contador2></contador2>
    <contador2></contador2>
</div>

<script src="../lib/vue.js"></script>
<script>
    // Registro GLobal
    // Vue.component('contador', {
    //     template: `
    //       <div>
    //       <span>{{contador}}</span>
    //       <button @click="contador++"> + </button>
    //       <button @click="contador--"> - </button>
    //       </div>
    //     `,
    //     data(){
    //         return {
    //             contador: 0
    //         }
    //     }
    // });

    const contador = {
        template: `
          <div>
          <span>{{contador}}</span>
          <button @click="contador++"> + </button>
          <button @click="contador--"> - </button>
          </div>
        `,
        data(){
            return {
                contador: 0
            }
        }
    };

    new Vue({
        el: '#app1',
        // REGISTRO LOCAL
        components:{
            contador1: contador
        }
    });


    new Vue({
        el: '#app2',
        // REGISTRO LOCAL
        components:{
            contador2: contador
        }
    });
</script>
  1. Criar Projeto Usando Vue CLI
  1. Criar um Componente
  1. Usando Componentes
  1. Usando CSS com Escopo de Componente
<style scoped>
span {
  border-bottom: 1px solid #CCC;
  height: 30px;
  padding: 5px 25px;
}

button {
  height: 30px;
  width: 30px;
  border-radius: 15px;
  background-color: coral;
  color: #fff;
  margin-left: 10px;
  outline: none;
}
</style>
  1. Hora de Praticar: Organizar Projeto em Componentes
  1. Hora de Praticar: Organizar Projeto em Componentes (Resposta)

  2. Organizando os Componentes em Pastas

import Menu from      "@/components/template/Menu.vue";
import Footer from    "@/components/template/Footer.vue";
import Caroussel from "@/components/widgets/Caroussel.vue";
import Toolbar from   "@/components/template/Toolbar.vue";

  1. Regras de Nomes de Componentes
<template>
  <v-app>

    <Menu />

    <Toolbar />

    <v-content>
      <Caroussel />
    </v-content>

    <Footer />

  </v-app>
</template>

<script>
import Menu from      "@/components/template/Menu.vue";
import Footer from    "@/components/template/Footer.vue";
import Caroussel from "@/components/widgets/Caroussel.vue";
import Toolbar from   "@/components/template/Toolbar.vue";

export default {
  components: {
     Footer,
     Caroussel,
     Toolbar,
     Menu
  },
}
</script>
  1. Conclusão do Módulo

  2. Recursos do Módulo & Links Úteis

Se você quiser aprender mais sobre componentes Vue JS, você talvez queira olhar esse artigo da documentação oficial:

https://br.vuejs.org/v2/guide/components.html

Importante: Alguns assuntos serão abordados nos próximos módulos do curso!

Também ver: https://br.vuejs.org/v2/guide/components-registration.html

Voltar ao Índice


  1. Introdução do Módulo

  2. Comunicação Entre Componentes

  1. Comunicação Direta com Props #01

  2. Comunicação Direta com Props #02

  3. Nome das Propriedades são Case-Sensitive

  4. Usando Props no Componente Filho

  5. Validando Props #01

  6. Validando Props #02

<script>
export default {
  //props: ['nome'],
  props: {
    sobrenome: String,
    nome: {
      type: String,
      default: 'Anônimo',
      // default: function(){
      //   return Array(5).fill(0).join(',')
      // },
      required: true
    },
    idade: [Number, String]
  },
  methods: {
    inverterNome() {
      return this.nome.split('').reverse().join('')
    }
  }
}
</script>
  1. Comunicação Indireta com Eventos Personalizados

  2. Comunicação Indireta com Callback

  3. Problema da Comunicação entre Componentes Irmãos

  4. Comunicação entre Componentes Irmãos

  5. Usando Event Bus para Comunicação entre Componentes Irmãos #01

  6. Usando Event Bus para Comunicação entre Componentes Irmãos #02

  7. Adicionando Métodos no Event Bus

import Vue from 'vue';

export default new Vue({

    methods: {
        alterarIdade(idade){
            this.$emit('idadeMudou', idade)
        },
        quandoIdadeMudar(callback){
            this.$on('idadeMudou', callback)
        }
    }


});
  1. Hora de Praticar: Comunicação entre Componentes

  2. Hora de Praticar: Comunicação entre Componentes (Resposta)

  3. Props por Valor vs Props por Referência

  4. Conclusão do Módulo

  5. Recursos do Módulo & Links Úteis

Links Úteis:

Documentação Oficial - Props: https://br.vuejs.org/v2/guide/components.html#Passando-Dados-aos-Filhos-com-Props

Documentação Oficial - Eventos Personalizados: https://br.vuejs.org/v2/guide/components.html#Enviando-Mensagens-ao-Pai-com-Eventos

Voltar ao Índice


  1. Introdução do Módulo

  2. Configurando Projeto do Módulo

  3. Como Passar Conteúdo no Corpo do Componente?

  4. Passando Conteúdo com Slots

  5. Como o Conteúdo do Slot é Estilizado

  6. Usando Múltiplos Slots (Slots Nomeados)

<template>
    <div class="citacao">
      <slot name="autor"></slot>
      <slot name="texto"></slot>
      <slot name="fonte"></slot>
    </div>
</template>
    <Citacao>
      <h1 slot="autor">{{citacoes[indice].autor}}</h1>
      <p slot="texto">{{ citacoes[indice].texto }}</p>
      <h6 slot="fonte">{{citacoes[indice].fonte}}</h6>
    </Citacao>
  1. Usando Slot Padrão

  2. Resumo sobre Slots

  3. Alternando entre Múltiplos Componentes com Componentes Dinâmicos

<template>
  <div id="app">
    <!--		<Citacoes />
        <Sobre />-->
    <span>
      <button @click="componente = 'Citacoes'">Citações</button>
      <button @click="componente = 'Sobre'">Sobre</button>
    </span>
    <component :is="componente"/>
  </div>
</template>

<script>
import Citacoes from './components/Citacoes'
import Sobre from './components/Sobre'

export default {
  components: {Citacoes, Sobre},
  data() {
    return {
      componente: 'Citacoes'
    }
  }
}
</script>
  1. Entendendo o Comportamento do Componente Dinâmico

  2. Mantendo o Componente Dinâmico Vivo

    <keep-alive>
      <component :is="componente"/>
    </keep-alive>
  1. Métodos de Ciclo de Vida de um Componente Dinâmico
<script>
export default {
  /*props:['texto']*/
  created() {
    console.log('created');
  },
  destroyed() {
    console.log('destroyed');
  },
  activated() {
    console.log('activated');
  },
  deactivated() {
    console.log('deactivated');
  }
}
</script>
  1. Hora de Praticar - Slots e Componentes Dinâmicos

  2. Hora de Praticar - Slots e Componentes Dinâmicos (Resposta)

  3. Conclusão do Módulo

  4. Recursos do Módulo & Links Úteis

Links Úteis:

Voltar ao Índice


  1. Introdução do Módulo

  2. Configurar Projeto

  1. Componente Lista de Tarefas #01

  2. Componente Tarefa #01

  3. Componente Lista de Tarefas #02

  4. Componente Nova Tarefa #01

  5. Componente Nova Tarefa #02

  6. Componente Tarefa #02

  7. Componente Tarefa #03

  8. Componente Progresso

  9. Usando Local Storage

  10. Conclusão do Módulo

  11. Recursos do Módulo & Links Úteis

Voltar ao Índice


  1. Introdução do Módulo

  2. Configurando Projeto do Módulo

  1. Ligação básica em Formulário usando

  2. Agrupando Dados e Pré-populando Inputs

  3. Modificar Entrada de Usuário com Modificadores de Input

  4. Usando textarea e Salvando Quebras de Linha

  5. Usando Checkboxes e Salvando os Dados em um Array

  6. Usando Botões Radio

  7. Manipulando Combobox com select e option

  8. O que o v-model faz e Como criar um Input Personalizado

  9. Submetendo Formulário

  10. Hora de Praticar - Formulários

  11. Hora de Praticar - Formulários (Resposta)

  1. Conclusão do Módulo

  2. Recursos do Módulo & Links Úteis

Links Úteis:

Documentação Oficial - Formulário: https://br.vuejs.org/v2/guide/forms.html

Voltar ao Índice


  1. Introdução do Módulo

  2. Entendendo Diretivas

-Secao-12-Usando-e-Criando-Diretivas/181-Entendendo-Diretivas/diretivas-exercicios

<template>
	<div id="app">
		<h1>Diretivas</h1>
    <hr>
    <p v-text="'Usando Directivas <strong>v-text</strong>'"></p>
    <p v-html="'Usando Directivas <strong>v-html</strong>'"></p>
	</div>
</template>
  1. Como a Diretiva Funciona - Funções Gatilho (Hooks)

  2. Criando uma Diretiva Simples

Vue.directive('destaque', {
	bind(el, binding, vnode) {
		el.style.backgroundColor = 'lightgreen';
	}
})
  1. Passando Valor para Diretiva Personalizada
<template>
	<div id="app">
		<h1>Diretivas</h1>
    <hr>
    <p v-text="'Usando Directivas <strong>v-text</strong>'"></p>
    <p v-html="'Usando Directivas <strong>v-html</strong>'"></p>
    <p v-destaque="'red'">Testando Directivas</p>
    <p v-destaque="cor">Testando Directivas</p>
	</div>
</template>

<script>
export default {
	data(){
	  return{
	    cor: 'green'
    }
  }
}
</script>
Vue.directive('destaque', {
	bind(el, binding, vnode) {
		//el.style.backgroundColor = 'lightgreen';
		//el.style.backgroundColor = binding.value;
        let atraso = 0;
        if(binding.modifiers['atrasar']) atraso = 3000
        
        setTimeout(() => {
            if(binding.arg === 'fundo'){
                el.style.backgroundColor = binding.value
            }else{
                el.style.color = binding.value;
            }
        })
	}
})
  1. Passando Argumento para Diretiva Personalizada
    <p v-destaque:fundo="'lightblue'">Testando Directivas</p>
    <p v-destaque="cor">Testando Directivas</p>
Vue.directive('destaque', {
	bind(el, binding, vnode) {
		//el.style.backgroundColor = 'lightgreen';
		//el.style.backgroundColor = binding.value;
		if(binding.arg === 'fundo'){
			el.style.backgroundColor = binding.value;
		}else{
			el.style.color = binding.value;
		}
	}
})
  1. Modificando Diretivas Personalizadas com Modificadores
Vue.directive('destaque', {
    bind(el, binding, vnode) {

        // eslint-disable-next-line no-unused-vars
        let atraso = 0;

        if (binding.modifiers['atrasar']) {
            atraso = 3000;
        }
        setTimeout(() => {

            if (binding.arg === 'fundo') {
                el.style.backgroundColor = binding.value;
            } else {
                el.style.color = binding.value;
            }
        },atraso);
    }
})
    <p v-destaque:fundo.atrasar="'lightblue'">Testando Directivas</p>
    <p v-destaque.atrasar="cor">Testando...</p>
  1. Resumo sobre Diretivas Personalizadas

  2. Registrando Diretivas Localmente

export default {
  components: {},
  directives: {
    'destaque-local': {
      bind(el, binding, vnode) {

        // eslint-disable-next-line no-unused-vars
        let atraso = 0;

        if (binding.modifiers['atrasar']) {
          atraso = 3000;
        }
        setTimeout(() => {

          if (binding.arg === 'fundo') {
            el.style.backgroundColor = binding.value;
          } else {
            el.style.color = binding.value;
          }
        },atraso);
      }
    }
  },
  data() {
    return {
      cor: 'blue'
    }
  }
}
  1. Usando Múltiplos Modificadores
export default {
  components: {},
  directives: {
    'destaque-local': {
      bind(el, binding, vnode) {

        const aplicarCor = cor => {
          if (binding.arg === 'fundo') {
            el.style.backgroundColor = cor;
          } else {
            el.style.color = cor;
          }
        }

        let atraso = 0;

        const cor1 = binding.value;
        const cor2 = 'purple';
        let corAtual = cor1;

        if (binding.modifiers['atrasar']) {
          atraso = 3000;
        }

        setTimeout(() => {
          setInterval(() => {
            if (binding.modifiers['alternar']) {
              corAtual = corAtual === cor1 ? cor2 : cor1;
              aplicarCor(corAtual)
            } else {
              aplicarCor(binding.value)
            }
          }, 1000);
        }, atraso);
      }
    }
  },
  data() {
    return {
      cor: 'blue'
    }
  }
}
    <p v-destaque-local:fundo.atrasar.alternar="'lightblue'">Testando Directivas</p>
    <p v-destaque-local.atrasar="cor">Testando...</p>
  1. Passando Valores mais Complexos para as Diretivas
export default {
  components: {},
  directives: {
    'destaque-local': {
      bind(el, binding, vnode) {

        const aplicarCor = cor => {
          if (binding.arg === 'fundo') {
            el.style.backgroundColor = cor;
          } else {
            el.style.color = cor;
          }
        }

        let atraso = 0;

        const cor1 = binding.value.cor1;
        const cor2 = binding.value.cor2;
        let corAtual = cor1;

        if (binding.modifiers['atrasar']) {
          atraso = binding.value.atraso;
        }

        setTimeout(() => {
          if (binding.modifiers['alternar']) {
            setInterval(() => {
              corAtual = corAtual === cor1 ? cor2 : cor1;
              aplicarCor(corAtual)
            }, binding.value.intervalo);
          } else {
            aplicarCor(binding.value.cor1)
          }
        }, atraso);
      }
    }
  },
  data() {
    return {
      cor: 'blue'
    }
  }
}
    <p v-destaque-local:fundo.atrasar.alternar="{cor1: 'green', cor2: 'red', atraso:3000, intervalo: 2000}">Testando
      Directivas</p>
    <p v-destaque-local.atrasar="{cor1:'red', atraso: 5000}">Testando...</p>
  1. Hora de Praticar - Diretivas
  1. Hora de Praticar - Diretivas (Resposta)
   <button v-quando:click="acao">EXECUTAR</button>
    <p v-quando:mouseenter="mouseEnter" v-quando:mouseleave="mouseLeaver">Teste de mouse event</p>
export default {
  directives: {
    quando: {
      bind(el, binding) {
        // el.onclick = function (e) {
        //   binding.value();
        // }
        const tipo = binding.arg;
        const fn = binding.value;
        el.addEventListener(tipo, fn);
      }
    }
  },
  methods: {
    acao() {
      alert('Ação Executada');
    },
    mouseEnter(){
      console.log('Passou o mouse!')
    },
    mouseLeaver() {
      console.log('Saiu o mouse!')
    }
  }
}
  1. Conclusão do Módulo

  2. Recursos do Módulo & Links Úteis

Links Úteis:

Documentação Oficial - Diretivas Personalizadas: https://br.vuejs.org/v2/guide/custom-directive.html

Voltar ao Índice


  1. Introdução do Módulo
  1. Criando um Filtro Local
<template>
  <div id="app">
    <h1>Filtros & Mixins</h1>
    <hr>
    <p>{{ cpf | cpf }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      cpf: '09856723412'
    }
  },
  filters: {
    cpf(valor) {
      const arr = valor.split('');
      arr.splice(3,0, '.')
      arr.splice(7,0, '.')
      arr.splice(11,0, '-')
      return arr.join('')
    }
  }
}
</script>
  1. Filtro Global e Como Encadear Múltiplos Filtros
Vue.filter('inverter', function (valor) {
	return valor.split('').reverse().join('');
});
  1. Filtro & v-bind
<template>
  <div id="app">
    <h1>Filtros & Mixins</h1>
    <hr>
    <p>{{ cpfAluno | cpf | inverter}}</p>
    <input type="text" :value="cpfAluno | cpf | inverter">
  </div>
</template>
  1. Duplicando Código para Usar os Mixins

  2. Criando e Usando Mixins

<template>
  <div id="app">
    <h1>Filtros & Mixins</h1>
    <hr>
    <p>Usuário Logado: {{usuarioLogado}}</p>
    <p>{{ cpfAluno | cpf | inverter }}</p>
    <input type="text" :value="cpfAluno | cpf | inverter">
    <hr>
    <Fruta/>
    <hr>
    <ul>
      <li v-for="fruta in frutas" :key="fruta">{{fruta}}</li>
    </ul>
    <input type="text" v-model="fruta" @keydown.enter="add">
  </div>
</template>

<script>
import frutasMixin from './frutasMixin';
import Fruta from "./Fruta.vue";
import usuarioLogado from "./usuarioLogado";

export default {
  components: {Fruta},
  mixins : [frutasMixin, usuarioLogado],
  data() {
    return {
      cpfAluno: '09856723412',
      frutas: ['abacate']
    }
  },
  filters: {
    cpf(valor) {
      const arr = valor.split('');
      arr.splice(3, 0, '.')
      arr.splice(7, 0, '.')
      arr.splice(11, 0, '-')
      return arr.join('')
    }
  },
  methods: {

  }
}
</script>
  1. Criando um Mixin Global (Caso Especial!)

  2. Hora de Praticar - Filtros & Mixins

  1. Hora de Praticar - Filtros & Mixins (Resposta)
<template>
  <div id="app">
    <h1>Filtros & Mixins (Desafio)</h1>
    <!-- Exercício 1 -->
    <!-- Construir um filtro local que troca espaços por vírgula -->
    <p>{{ frase | espaco-por-virgula }}</p>
    <p>{{ frase | espacoPorVirgula }}</p>


    <!-- Exercício 2 -->
    <!-- Filtro global que conta o tamanho de cada palavra e adiciona o
      valor na string final -->
    <!-- "Pedro é legal" => "Pedro (5) é (1) legal (5)" -->
    <p>{{ frase | contar-palavras }}</p>
    <p>{{ frase | contarPalavras }}</p>

    <!-- Exercício 3 -->
    <!-- Implementar os exercicios 1 e 2 com propriedade computada -->
    <p>{{ fraseComVirgulas }}</p>
    <p>{{ fraseComTanhamo }}</p>

    <!-- Exercício 4 -->
    <!-- Compartilhe a propriedade computada via mixin -->
  </div>
</template>

<script>
import fraseMixin from "./fraseMixin";

export default {
  mixins:[fraseMixin] ,
  data() {
    return {
      frase: 'Essa é a frase que será usada nos desafios'
    }
  },
  filters: {
    espacoPorVirgula(valor) {
      return valor.replace(/\s/g, ',')
    }
  },
  computed: {
    // fraseComVirgulas() {
    //   return this.frase.replace(/\s/g, ',')
    // },
    // fraseComTanhamo(){
    //   return this.frase.split(' ').map(p => `${p} (${p.length})`).join(' ')
    // }
  }
}
</script>
export default {
    computed: {
        fraseComVirgulas() {
            return this.frase.replace(/\s/g, ',')
        },
        fraseComTanhamo(){
            return this.frase.split(' ').map(p => `${p} (${p.length})`).join(' ')
        }
    }
}
Vue.filter('contarPalavras', function (valor) {
    return valor.split(' ').map(p => `${p} (${p.length})`).join(' ')
});
  1. Conclusão do Módulo

  2. Recursos do Módulo & Links Úteis

Links Úteis:

Voltar ao Índice


  1. Introdução do Módulo

  2. Entendendo as Transições

  3. Preparando o Código para Usar Transições

  1. Configurando Transição

img/transicao_css.png

  1. Definindo as Classes CSS para Transição

  2. Criando Transição "Fade" com Propriedade CSS transition

    <transition name="fade">
      <b-alert variant="info" show v-if="exibir">{{ msn }}</b-alert>
    </transition>
// ...
<style>
.fade-enter, .fade-leave-to {
  opacity: 0;
}

.fade-enter-active, .fade-leave-active  {
  transition: opacity 2s;
}

/*.fade-enter-to {
opacity: 1;
}

.face-leave {
opacity: 1;
}*/

/*.fade-leave-active {
transition: opacity 2s;
}*/

/*.fade-leave-to {
opacity: 0;
}*/
</style>
  1. Criando Transição "Slide" com Propriedade CSS animation

  2. Misturando as Propriedades transition e animation

<transition name="slide" type="animation">
<b-alert variant="info" show v-if="exibir">{{ msn }}</b-alert>
</transition>
// ....
<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
  font-size: 1.5rem;
}

.fade-enter, .fade-leave-to {
  opacity: 0;
}

.fade-enter-active, .fade-leave-active {
  transition: opacity 2s;
}

@keyframes slide-in {
  from {
    transform: translateY(40px);
  }
  to {
    transform: translateY(0);
  }
}

@keyframes slide-out {
  from {
    transform: translateY(0);
  }
  to {
    transform: translateY(40px);
  }
}

.slide-enter-active {
  animation: slide-in 2s ease;
  transition: opacity 2s;
}

.slide-leave-active {
  animation: slide-out 2s ease;
  transition: opacity 6s;
}

.slide-enter, .slide-leave-to{
  opacity: 0;
}
</style>
  1. Usando v-show
<transition name="slide" type="animation">
  <!--      <b-alert variant="info" show v-if="exibir">{{ msn }}</b-alert>-->
  <b-alert variant="info" show v-show="exibir">{{ msn }}</b-alert>
</transition>
  1. Configurando Animação no Carregamento do Componente
    <transition name="fade" appear>
      <b-alert variant="info" show v-if="exibir">{{ msn }}</b-alert>
    </transition>
  1. Usando Nomes Diferentes de Classes CSS
<transition
  enter-active-class="animated bounce"
  leave-active-class="animated shake"
>
  <b-alert variant="info" show v-if="exibir">{{ msn }}</b-alert>
</transition>
  1. Usando Nomes e Atributos Dinâmicos
    <b-select v-model="tipoAnimacao" class="mb-4">
      <option value="fade">Fade</option>
      <option value="slide">Slide</option>
    </b-select>
    <transition :name="tipoAnimacao">
      <b-alert variant="info" show v-show="exibir">{{ msn }}</b-alert>
    </transition>
  1. Transicionar entre Múltiplos Elementos
    <transition :name="tipoAnimacao" mode="out-in">
      <b-alert variant="info"    show key="info" v-if="exibir">{{ msn }}</b-alert>
      <b-alert variant="warning" show key="warn" v-else>{{ msn }}</b-alert>
    </transition>
  1. Escutando a Eventos de Transição (Hooks)

img/transicao_js.png

  1. Entendendo Animação em JavaScript
<button @click="exibir2 = !exibir2">Mostrar</button>
    <transition
      @before-enter="beforEnter"
      @enter="enter"
      @after-enter="afterEnter"
      @enter-cancelled="enterCancelled"

      @before-leave="beforeLeave"
      @leave="leave"
      @after-leave="afterLeave"
      @leave-cancelled="leaveCancelled"
    >
      <div class="caixa" v-if="exibir2"></div>
    </transition>
methods: {
    beforEnter(el){
      console.log('beforEnter')
    },
    enter(el, done){
      console.log('enter')
      done()
    },
    afterEnter(el){
      console.log('AfterEnter')
    },
    enterCancelled() {
      console.log('EnterCancelled');
    },
    beforeLeave(el) {
      console.log('beforLeave');
    },
    leave(el, done) {
      console.log('Leave');
      done()
    },
    afterLeave(el) {
      console.log(afterLeave)
    },
    leaveCancelled(){
      console.log('leaveCancelled')
    }
  }
  1. Excluindo CSS da Animação
    <transition
        :css="false"
      @before-enter="beforEnter"
      @enter="enter"
      @after-enter="afterEnter"
      @enter-cancelled="enterCancelled"

      @before-leave="beforeLeave"
      @leave="leave"
      @after-leave="afterLeave"
      @leave-cancelled="leaveCancelled"
    >
      <div class="caixa" v-if="exibir2"></div>
    </transition>
  1. Criando Animação em JavaScript
methods: {
    animar(el, done, negativo) {
      let rodada = 1
      const temporizador = setInterval(() => {
        const novaLargura = this.larguraBase +
            (negativo ? -rodada * 10 : rodada * 10)
        el.style.width = `${novaLargura}px`
        rodada++
        if (rodada > 30) {
          clearInterval(temporizador)
          done()
        }
      }, 20)
    },
    beforEnter(el) {
      this.larguraBase = 0
      el.style.width = `${this.larguraBase}px`
    },
    enter(el, done) {
      this.animar(el, done, false)
    },
    /*    afterEnter(el){
          console.log('AfterEnter')
        },*/
    /*    enterCancelled() {
          console.log('EnterCancelled');
        },*/
    beforeLeave(el) {
      this.larguraBase = 300
      el.style.width = `${this.larguraBase}px`
    },
    leave(el, done) {
      this.animar(el, done, true)
    },
    /*    afterLeave(el) {
          console.log(afterLeave)
        },
        leaveCancelled(){
          console.log('leaveCancelled')
        }*/
  }
  1. Animando Componentes Dinâmicos
<div class="mb-4">
      <b-button class="mr-2" variant="primary" @click="componenteSelecionado = 'AlertaInfo'">Info</b-button>
      <b-button variant="secondary" @click="componenteSelecionado = 'AlertaAdvertencia'">Advertência</b-button>
    </div>
    <transition name="fade" mode="out-in">
      <component :is="componenteSelecionado"></component>
    </transition>
  1. Animando Listas com

  2. Usando - Preparações

  3. Usando para Animar Listas

<b-button @click="adicionaAluno" class="mb-4">Admicionar Aluno</b-button>
    <transition-group name="slide" tag="div">
      <b-list-group v-for="(aluno, i) in alunos" :key="aluno">
        <b-list-group-item @click="removeAluno(i)">{{ aluno }}</b-list-group-item>
      </b-list-group>
    </transition-group>
  1. Entendendo a Aplicação
  1. Desenvolvendo a Aplicação #01

  2. Desenvolvendo a Aplicação #02

  3. Adicionando as Animações

  4. Conclusão do Módulo

  5. Recursos do Módulo & Links Úteis

Voltar ao Índice


  1. Introdução do Módulo

  2. Configuração do Firebase

  3. Configuração Global do Axios

import Vue from 'vue';
import axios from 'axios';

axios.defaults.baseURL = 'https://**********c34-default-rtdb.firebaseio.com/';

Vue.use({
    install(Vue) {
        Vue.prototype.$http = axios;
    }
})
  1. Criando Instância do Axios
import Vue from 'vue';
import axios from 'axios';

//axios.defaults.baseURL = 'https://curso-vue-2-26c34-default-rtdb.firebaseio.com/';

Vue.use({
    install(Vue) {
        //Vue.prototype.$http = axios;

        Vue.prototype.$http = axios.create({
            baseURL: 'https://c********-default-rtdb.firebaseio.com/'
        })

    }
})
  1. Criando Formulário

  2. Enviando POST

 methods:{
    salvar(){
      this.$http.post('usuarios.json', this.usuario)
      .then(resp => {
        this.usuario.nome = ''
        this.usuario.email = ''
      })
    }
  }
  1. Enviando GET
obterUsuarios(){
      //this.$http.get()
      this.$http('usuarios.json')
      .then(res => {
        this.usuarios = res.data;
      })
    }
  1. Usando Axios Localmente
<script>
import axios from 'axios';

    obterUsuarios(){
    //this.$http.get()
    axios('https://curso-vue-2-26c34-default-rtdb.firebaseio.com/usuarios.json')
        //this.$http('usuarios.json')
        .then(res => {
            this.usuarios = res.data;
        })
  1. Interceptando Requisições
Vue.use({
    install(Vue) {
        //Vue.prototype.$http = axios;

        Vue.prototype.$http = axios.create({
            baseURL: 'https://curso-vue-2-26c34-default-rtdb.firebaseio.com/'
        })

        Vue.prototype.$http.interceptors.request.use(config => {
            console.log(config.method);

/*            if (config.method == 'post') {
                config.method = 'put'
            }*/

            return config;
        });

    }
})
  1. Interceptando Resposta
Vue.use({
    install(Vue) {
        //Vue.prototype.$http = axios;

        Vue.prototype.$http = axios.create({
            baseURL: 'https://curso-vue-2-26c34-default-rtdb.firebaseio.com/'
        })

        Vue.prototype.$http.interceptors.request.use(config => {
            console.log(config.method);

/*            if (config.method == 'post') {
                config.method = 'put'
            }*/

            return config;
        }, error => {Promise.reject(error)});

        Vue.prototype.$http.interceptors.response.use(res => {
            const array = []
            for(let chave in res.data){
                array.push({id: chave, ...res.data[chave]});
            }
            res.data = array;
            return res
        }, error => {Promise.reject(error)})

    }
})
  1. Adicionando Headers Globais
// axios.defaults.headers.common['Authorization'] = 'abc123';
// axios.defaults.headers.get['Accepts'] = 'application/json*';
  1. Implementando CRUD
  1. Exibindo Mensagens
<b-alert show
         dismissible
         v-for="mensagem in mensagens"
             :key="mensagem.texto"
:variant="mensagem.tipo"
    >{{mensagem.texto}}
</b-alert>

salvar() {
      // this.$http.post('usuarios.json', this.usuario)
      //     .then(() => {
      //       this.limpar()
      //     })
      const metodo    = this.id ? 'patch' : 'post'
      const finalUrl  = this.id ? `/${this.id}.json`: '.json'
      this.$http[metodo](`/usuarios${finalUrl}`, this.usuario)
          .then(() => {
            this.limpar();
            this.mensagens.push({
              texto: 'Operação realizada com sucesso!',
              tipo: 'success'
            })
          });
    },
  1. Conclusão do Módulo

  2. Recursos do Módulo & Links Úteis

Voltar ao Índice


  1. Introdução do Módulo

  2. Instalação do vue-router

  • [Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios](Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios)
  1. Configuração do vue-router
  • [Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/router.js](Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/router.js)
import Vue from 'vue';
import Router from 'vue-router';
import Inicio from './components/Inicio';
import Usuario from './components/usuario/Usuario';

Vue.use(Router);

export default new Router({
    routes:[{
        path: '/',
        component:Inicio
    },
        {
            path: '/usuario',
            component: Usuario
        }]
})
  1. Entendendo os Modos de Rotas (Hash vs History)
  • [Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/router.js](Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/router.js)
export default new Router({
    mode: 'history',
    routes:[{
        path: '/',
        component:Inicio
    },
        {
            path: '/usuario',
            component: Usuario
        }]
})
  1. Navegando com Router Links
  • [Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/components/template/Menu.vue](Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/components/template/Menu.vue)
<template>
    <nav class="menu">
        <router-link to="/">Início</router-link>
        <router-link to="/usuario">Usuário</router-link>
    </nav>
</template>
  1. Onde estou? - Estilizando o Link Ativo
  • [Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/components/template/Menu.vue](Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/components/template/Menu.vue)
<template>
  <nav class="menu">
    <ul>
      <router-link to="/" tag="li" active-class="active" exact>
        <a>Início</a></router-link>
      <router-link to="/usuario" tag="li" active-class="active" >
        <a>Usuário</a></router-link>
    </ul>
  </nav>
</template>
  1. Navegação via Código (Navegação Imperativa)
  • [Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/components/usuario/Usuario.vue](Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/components/usuario/Usuario.vue)
<template>
<div class="usuario">
  <h2>Usuário</h2>
  <hr>
  <button sucesso @click="irParaInicio">Voltar</button>
</div>
</template>

<script>
export default {
  name: "Usuario",
  methods:{
    irParaInicio(){
      //this.$router.push('/')
      this.$router.push({
        path: '/'
      });
    }
  }
}
</script>

<style scoped>

</style>
  1. Configurando Parâmetros de Rotas
  • [Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/router.js](Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/router.js)
export default new Router({
    mode: 'history',
    routes:[{
        path: '/',
        component:Inicio
    },
        {
            path: '/usuario/:id',
            component: Usuario
        }]
})
  1. Lendo e Usando Parâmetros de Rotas

  2. Reagindo a Mudanças em Parâmetros de Rotas

  • [Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/components/usuario/Usuario.vue](Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/components/usuario/Usuario.vue)
<template>
  <div class="usuario">
    <h2>Usuário</h2>
    <hr>
    <p><strong>Código:</strong>{{ id }}</p>
    <button sucesso @click="irParaInicio">Voltar</button>
  </div>
</template>

<script>
export default {
  name: "Usuario",
  data(){
    return{
      id: this.$route.params.id
    }
  },
  watch:{
    $route(to, from){
      this.id = to.params.id;
    }
  },
  methods: {
    irParaInicio() {
      //this.$router.push('/')
      this.$router.push({
        path: '/'
      });
    }
  }
}
</script>
  1. Parâmetros de Rotas via "props"
  • [Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/components/usuario/Usuario.vue](Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/components/usuario/Usuario.vue)
export default {
  name: "Usuario",
  // data(){
  //   return{
  //     id: this.$route.params.id
  //   }
  // },
  // watch:{
  //   $route(to, from){
  //     this.id = to.params.id;
  //   }
  // },
  props: ['id'],
  methods: {
    irParaInicio() {
      //this.$router.push('/')
      this.$router.push({
        path: '/'
      });
    }
  }
}
</script>
  1. Configurando Rotas Filhas (Rotas Aninhadas)
  • [Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/router.js](Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/router.js)
export default new Router({
    mode: 'history',
    routes: [{
        path: '/',
        component: Inicio
    },
        {
            path: '/usuario',
            component: Usuario,
            props: true,
            children: [
                {path: '', component: UsuarioLista},
                {path: ':id', component: UsuarioDetalhe, props: true},
                {path: ':id/editar', component: UsuarioEditar, props: true},
            ]
        }]
})
  1. Navegando para Rotas Aninhadas

  2. Tornando Router Links mais Dinâmico

  3. Criando Links com Rotas Nomeadas

  • [Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/router.js](Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/router.js)
 {
            path: '/usuario',
            component: Usuario,
            props: true,
            children: [
                {path: '', component: UsuarioLista},
                {path: ':id', component: UsuarioDetalhe, props: true},
                {path: ':id/editar',
                    component: UsuarioEditar,
                    props: true,
                    name: 'editarUsuario'},
            ]
        }
  1. Usando Parâmetros da Query
  • [Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/components/usuario/UsuarioDetalhe.vue](Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/components/usuario/UsuarioDetalhe.vue)
 <router-link primario
                 :to="{ name:'editarUsuario',
                        params: {id},
                        query: {
                          completo: true,
                          lingua: 'pt'
                    }
                        }"
                 tag="button">Editar
    </router-link>
<template>
  <div class="usuario-editar">
    <h3>Usuário Ediatar</h3>
    <hr>
    <p><strong>Código: </strong>{{ id }}</p>
    <p><strong>Completo: </strong>{{$route.query.completo ? 'Sim' : 'Não'}}</p>
    <p><strong>Língua: </strong>{{$route.query.lingua}}</p>
  </div>
</template>
  1. Múltiplos Router Views (Router Views Nomeados)
  • [Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/router.js](Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/router.js)
 components: {
default: Usuario,
        menu: MenuAlt,
        menuInferior: Menu
},
<template>
  <div id="app">
    <h1>Rotas com VueRouter</h1>
    <router-view name="menu"></router-view>
    <router-view />
    <router-view name="menuInferior"></router-view>
  </div>
</template>
  1. Redirecionamento
  • [Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/router.js](Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/router.js)
        {
            path: '/redirecionar',
            redirect: '/usuario'
        }
  1. Configurando Rota "Pega Tudo"
  • [Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/router.js](Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/router.js)
        {
            path: '*',
            redirect: '/'
        }
  1. Animando Transições de Rotas
  • [Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/App.vue](Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/App.vue)
   <transition
        mode="out-in"
        enter-active-class="animated rubberBand"
        leave-active-class="animated rollOut"
    >
      <router-view />
    </transition>
  1. Passando Fragmento Hash

  2. Controlando o Comportamento de Rolagem (Scroll)

  • [Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/router.js](Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/router.js)
  scrollBehavior(to, from, savedPosition){
        if(savedPosition){
            return savedPosition;
        }else if(to.hash){
          return {selector: to.hash}
      }else{
            return {x: 0, y:o}
        }
    },
  1. Protegendo Rotas

  2. Usando o Evento "beforeEnter"

 {path: ':id', component: UsuarioDetalhe, props: true,
                    beforeEnter: (to, from, next) => {
                        console.log('antes da rota -> usuario detalhe')
                        next();
                    }
                }
 beforeRouteEnter(to, from, next) {
    //console.log(this.id) // erro
    console.log(' dentro do componente -> usuario detalhe')
    next(vm => {
      console.log(vm.id); // acesso ao id do componente
    })
    const autenticado = true;
    autenticado ? next() : next(false);
  }
  1. Usando o Evento "beforeLeave"
  • [Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/components/usuario/UsuarioEditar.vue](Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/components/usuario/UsuarioEditar.vue)
beforeRouteLeave(to, from, next) {
    if (this.confirmou) {
      next();
    }else{
      if (confirm('Tem certeza?')) {
        next();
      }else{
        next(false);
      }
    }
  }
  1. Carregando Rotas Tardiamente
  • [Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/router.js](Secao-16-Rotas-em-um- Aplicacao-VueJS/rotas-exercicios/src/router.js)
import Menu from './components/template/Menu';
//import Usuario from './components/usuario/Usuario';
//import UsuarioLista from "./components/usuario/UsuarioLista";
//import UsuarioDetalhe from "./components/usuario/UsuarioDetalhe";
//import UsuarioEditar from "./components/usuario/UsuarioEditar";

import MenuAlt from "./components/template/MenuAlt";

Vue.use(Router);

const Usuario         = () => import(/* webpackChunkName: "usuario" */ './components/usuario/Usuario');
const UsuarioLista    = () => import(/* webpackChunkName: "usuario" */ './components/usuario/UsuarioLista')
const UsuarioDetalhe  = () => import(/* webpackChunkName: "usuario" */ '/components/usuario/UsuarioDetalhe')
const UsuarioEditar   = () => import(/* webpackChunkName: "usuario" */ '/components/usuario/UsuarioEditar')
  1. Conclusão do Módulo

  2. Recursos do Módulo & Links Úteis

Voltar ao Índice


  1. Introdução do Módulo

  2. Por que usar um Gerenciador de Estado?

  3. Entendendo "Estado Centralizado"

img/vuex_estado.png

  1. Conhecendo o Projeto do Módulo

  2. Usando Estado Centralizado

  3. Por que Estado Centralizado Sozinho Não Resolve

  4. Entendendo Getters

  5. Usando Getters

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
    state: {
        produtos: [
            {id: 1, nome: 'Produto 1', quantidade: 7, preco: 14.55},
            {id: 2, nome: 'Produto 2', quantidade: 10, preco: 22.99},
           // {id: 3, nome: 'Produto 3', quantidade: 1, preco: 43.18},
        ]
    },
    getters:{
        valorTotal(state) {
            return state.produtos.map(p => p.quantidade * p.preco)
                .reduce((total, atual) => total + atual, 0)
        }
    }
});
  1. Mapeando Getters para Propriedades
<template>
    <Painel titulo="Resumo" roxo>
        <div class="resumo">
            <span>Total: <strong>{{ total | dinheiro }}</strong></span>
            <hr>
            <button>Finalizar!</button>
        </div>
    </Painel>
</template>

<script>
import {mapGetters} from 'vuex';

export default {
    computed: mapGetters({
      total: "valorTotal"
    })
    //computed:mapGetters(['valorTotal'])
    /*computed: {
        total() {
          return this.$store.getters.valorTotal;
        },
        produtos() {
          return this.$store.state.produtos;
        }
    },*/

}
</script>
  1. Observação sobre o funcionamento da aplicação

Observação sobre o funcionamento da aplicação Fala, pessoal!

Um breve esclarecimento sobre um "bug" apresentado no desenvolvimento da aplicação usada nesse capítulo. Caso você tente alterar interagir com os valores no componente Loja Virtual, o console do navegador apresentará a seguinte mensagem de erro:

Computed property "quantidade" was assigned to but it has no setter

Ou:

Computed property "preco" was assigned to but it has no setter

Isso acontece porque em Loja Virtual para os campos preco e quantidade definimos apenas os getters para capturar os dados da store e não definimos os setters para modificar esses dados na store.

Caso você queira permitir a alteração dos dados na store através do componente Loja Virtual, você deve implementar os setters, assim como foi feito em Parâmetros. Veja o exemplo:

computed: {
    quantidade: {
        get () {
         return this.$store.state.parametros.quantidade
        },
        set (valor) {
            this.$store.commit('setQuantidade', valor)
        }
    },
    preco: {
        get () {
            return this.$store.state.parametros.preco
        },
        set (valor) {
            this.$store.commit('setPreco', valor)
        }
    }
},

Tenha em mente que agora o que for alterado em Loja Virtual será alterado em Parâmetros, mas esse não era o caso de uso planejado para essa aplicação. Tranquilo?

Esperamos que com essa aula artigo tenhamos esclarecido essa pequena confusão 😅

  1. Entendendo Mutations

img/mutattion.png

  1. Usando Mutations
    mutations:{
        adicionarProduto(state, payload) {
            state.produtos.push(payload);
        }
    }
    methods: {
      ...mapMutations(["adicionarProduto"]),
        adicionar() {
            const produto = {
                id: this.sequencia,
                nome: `Produto ${this.sequencia}`,
                quantidade: this.quantidade,
                preco: this.preco
            }
            this.sequencia++
            // eslint-disable-next-line
            //console.log(produto)

          //this.$store.state.produtos.push(produto)
          //this.$store.commit("adicionarProduto", produto);
          this.adicionarProduto(produto);

        }
    }
  1. Por que existem Mutations e Actions?

  2. Como Actions Complementam as Mutation

img/actions.png

  1. Usando Actions
actions:{
        //adicionarProduto(context, payload) {
        adicionarProduto({commit}, payload) {
            setTimeout(() => {
                commit('adicionarProduto', payload);
            }, 1000)
        }
import {mapActions} from 'vuex';

methods: {
...mapActions(["adicionarProduto"]),
        adicionar() {
        const produto = {
            id: this.sequencia,
            nome: `Produto ${this.sequencia}`,
            quantidade: this.quantidade,
            preco: this.preco
        }
        this.sequencia++
        // eslint-disable-next-line
        //console.log(produto)

        //this.$store.state.produtos.push(produto)
        //this.$store.commit("adicionarProduto", produto);

        this.adicionarProduto(produto);
        //this.$store.dispatch('adicionarProduto', produto);

    }
  1. Mapeando Actions para Métodos
    methods: {
      ...mapActions(["adicionarProduto"]),

/*      adicionarProduto(){
        this.$store.dispatch('adicionarProduto', produto);
      },*/
  1. Vuex e Two-Way-Binding (v-model)
 mutations: {
        adicionarProduto(state, payload) {
            state.produtos.push(payload);
        },
        setQuantidade(state, payload) {
            state.quantidade = payload;
        },
        setPreco(state, payload) {
            state.preco = payload;
        }
    },
export default {
  computed:{
   quantidade: {
     get() {
       return this.$store.state.quantidade;
     },
     set(valor) {
       this.$store.commit('setQuantidade', valor);
     }
   },
    preco:{
      get() {
        return this.$store.state.preco;
      },
      set(valor) {
        this.$store.commit('setPreco', valor);
      }
    }
  }
}
    computed:{
      quantidade() {
        return this.$store.state.quantidade;
      },
      preco(){
        return this.$store.state.preco;
      }
    },
  1. Resumo do Vuex

  2. Melhorando a Estrutura de Pastas

  3. Modularizando o Gerenciador de Estado

  4. Usando Arquivos Separados

export const getNome = state => state.nome
export const getNomeCompleto = state => state.nome + state.sobrenome
import carrinho from "./modules/carrinho";
import parametros from "./modules/parametros";

import * as getters from './getters';

Vue.use(Vuex);

export default new Vuex.Store({
    state:{
        nome: 'Jose',
        sobrenome: 'Malcher'
    },
    //getters,
    getters:{
      ...getters
    },
    modules:{carrinho, parametros}
});
          // eslint-disable-next-line
          console.log(this.$store.getters.getNome)
          // eslint-disable-next-line
          console.log(this.$store.getters.getNomeCompleto)
  1. Usando Namespaces para Evitar Conflitos de Nomes
export default{
    namespaced: true,
export default {
    computed: {
      ...mapGetters('carrinho',{
        total: 'valorTotal'
      }),
  1. Conclusão do Módulo

  2. Recursos do Módulo & Links Úteis

Voltar ao Índice


  1. Introdução do Projeto

  2. Debugando Vuex com Vue Developer Tools

  3. Configuração do Projeto

  1. Criando os Primeiros Componentes

  2. Configurando as Rotas do Projeto

  3. Adicionando Cabeçalho e Navegação

  4. Criando o Componente de Ações (Stocks)

  5. Adicionando o Botão Comprar

  6. Configurando o Vuex no Projeto

  7. Adicionando o Módulo Portfolio ao Vuex

  8. Trabalhando com Ações do Portfolio

  9. Conectando o Portfolio ao Vuex

  10. Exibindo o Saldo

  11. Adicionando Validações

  12. Aplicando Filtro de Valor Monetário no Saldo

  13. Finalizando Dia - Alterando Preço das Ações

  14. Animando a Transição de Rotas

  15. Configurando Axios & Firebase

  16. Salvando Dados (Requisição PUT)

  17. Obtendo Dados (Requisição GET)

  18. Conclusão do Módulo

  19. Recursos do Módulo & Links Úteis

Voltar ao Índice


Voltar ao Índice


Voltar ao Índice


Voltar ao Índice


Voltar ao Índice


Voltar ao Índice


Seção 24: Bonus: CSS Grid & Flexbox

Voltar ao Índice


  1. Função: Cidadão de Primeira Classe
//Função em JS é FirstClass Object (Citizens)
// Highter-order function

// cliar de forma literal
function fn1() {

}

// Armazenar em uma variável
const fn2 = function () {
}

// armazenar em um array
const array = [function (a, b) {
    return a + b
}, fn1, fn2]
console.log(array[0](2, 3));

//Armazenar em um atributo de objeto
const obj = {};
obj.falar = function () {
    return "Olá";
};
console.log(obj.falar());

// Passar função como param
function run(fun) {
    fun();
}

run(function () {
    console.log('Correndo por funções')
})

// uma função pode retornar/conter uma função
function soma(a, b) {
    return function (c) {
        console.log(a + b + c);
    };
}

//soma(2, 3)(4); // 9
const cincoMais = soma(3, 2);
cincoMais(4); //9
  1. Função: Parâmetros e Retorno São Opcionais

-Secao-25-Bonus-Javascript-Essencial/411-Funcao-Parametros-e-Retorno-Sao-Opcionais.js

function area(largura, altura) {
    const area = largura * altura;
    if (area > 20) {
        console.log(`Valor acima do permitido: ${area} m2`);
    }else{
        return area
    }
}

console.log(area(2,2)); // 4
console.log(area(2)); // NaN
console.log(area());// NaN
console.log(area(2,3,4,5)); // 5
console.log(area(10,10)); // Valor acima do permitido: 100 m2
// undefined
  1. Função: "this" pode Variar

  2. Função: "this" e a Função bind #01

const pessoa = {
    saudacao: 'Bom dia',
    falar(){
        console.log(this.saudacao);
    }
}

pessoa.falar()
const falar = pessoa.falar();

//falar(); // conflito entre paradigmas: funcional e OO

const falarDePessoa = pessoa.falar.bind(pessoa);
falarDePessoa()
  1. Função: "this" e a Função bind #02
function Pessoa(){
    this.idade = 0;

    const self = this;

    setInterval(function () {
        self.idade++
        console.log(self.idade);
    }/*.bind(this)*/,1000);
}
new Pessoa()
  1. Funções Arrow #01
let dobro = function (a) {
    return 2 * a;
}

dobro = (a) => {
    return 2 * a
}

dobro = a => 2 * a // retorno implícito
console.log(dobro(Math.PI));

let ola = function () {
    return 'Olá';
};

ola = () => 'Olá'
ola = _ => 'Olá' // possui um param
console.log(ola());
  1. Funções Arrow #02
function Pessoa(){
    this.idade = 0;

    setInterval(() => {
        this.idade++
        console.log(this.idade);
    }, 1000)
}

new Pessoa()
  1. Funções Arrow #03
let comparaComThis = function (param) {
    console.log(this === param)
};

comparaComThis(global); // global - escopo NODE
// true
const obj = {}
comparaComThis = comparaComThis.bind(obj)
comparaComThis(global); // false
comparaComThis(obj) // true

let comparaComThisArrow = param => console.log(this === param);
comparaComThisArrow(global); // false
comparaComThisArrow(module.exports) // true

comparaComThisArrow = comparaComThisArrow.bind(obj);
comparaComThisArrow(obj) // false
comparaComThisArrow(module.exports) // true
  1. Funções Anônimas
const soma = function (x, y) {
    return x + y;
};

const imprimeResultado = function (a, b, operacao = soma) {
    console.log(operacao(a, b))
};

imprimeResultado(3, 4);
imprimeResultado(3, 4, soma);
imprimeResultado(3, 4, function (x, y) {
    return x - y
});

imprimeResultado(3, 4, (x, y) => x * y);

const pessoa = {
    falar: function () {
        console.log('OLÁ!!!')
    },
    raiva() {
        console.log('GRRRRR!')
    }
}
pessoa.falar()
pessoa.raiva()
  1. Funções Callback #01
const fabricantes = ["Mercedes", "Audio", "BMW"];

function imprimir(nome, indice) {
    console.log(`${indice + 1}. ${nome}`);
}

fabricantes.forEach(imprimir);
fabricantes.forEach(fabricantes => console.log(fabricantes));
  1. Funções Callback #02
const notas = [7.7,6.6, 5.9, 5.5, 9.9, 8.9, 7.9];

// sem callback
let notasBaixas = []
for (let i in notas) {
    if (notas[i] < 7) {
        notasBaixas.push(notas[i])
    }
}
console.log(notasBaixas);

//Com call back
notasBaixas2 = notas.filter(function (nota) {
    return nota < 7;
});

console.log(notasBaixas2)

const notasMenorque7 = nota => nota < 7;
const notasBaixa3    = notas.filter(notasMenorque7);
console.log(notasBaixa3)
  1. Funções Callback #03
// exemplo de callback no browser

document.getElementsByTagName('body')[0].onclick = function (ev) {
    console.log('O evento ocorreu');
};
  1. Funções Construtoras
function Carro(velocidadeMaxima = 200, delta = 5) {
    //atributo privado
    let velocidadeAtual = 0;

    //Método Publico
    this.acelerar = function () {
        if (velocidadeAtual + delta <= velocidadeMaxima) {
            velocidadeAtual += delta;
        }else{
            velocidadeAtual = velocidadeMaxima;
        }
    };
    // Método Publico
    this.getVelocidadeAtual = function () {
        return velocidadeAtual;
    };
}

const uno = new Carro
uno.acelerar();
console.log(uno.getVelocidadeAtual());

const ferrari = new Carro(350, 20);
ferrari.acelerar();
ferrari.acelerar();
ferrari.acelerar();
ferrari.acelerar();
console.log(ferrari.getVelocidadeAtual());

console.log(typeof Carro)  //function
console.log(typeof ferrari) //object
  1. Array: Map #01
const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// For com propósito
let resultado = nums.map(function (value) {
    return value * 2;
});

console.log(resultado);

const soma10 = e => e + 10;
const triplo = e => e * 3;
const paraDinheiro = e => `R$ ${parseFloat(e).toFixed(2).replace('.', ',')}`;

resultado = nums.map(soma10).map(triplo).map(paraDinheiro)
console.log(resultado);
  1. Array: Map #02
const carrinho = [
    '{"nome": "borracha"         , "preco": 3.45}',
    '{"nome": "lapis"            , "preco": 0.45}',
    '{"nome": "Kit lapis de cor" , "preco": 10.45}',
    '{"nome": "Caneta"           , "preco": 1.45}',
]

// Retornar um array apenas com os preços

const paraObjeto = json => JSON.parse(json);
const apenasPreco = produto => produto.preco;

const resultado = carrinho.map(paraObjeto).map(apenasPreco);

console.log(resultado);
  1. Array: Map #03
Array.prototype.map2 = function (callback) {
    const newArray = [];
    for (let i = 0; i < this.length; i++) {
        newArray.push(callback(this[i], i, this));
    }
};

const carrinho = [
    '{"nome": "borracha"         , "preco": 3.45}',
    '{"nome": "lapis"            , "preco": 0.45}',
    '{"nome": "Kit lapis de cor" , "preco": 10.45}',
    '{"nome": "Caneta"           , "preco": 1.45}',
]

// Retornar um array apenas com os preços

const paraObjeto = json => JSON.parse(json);
const apenasPreco = produto => produto.preco;

const resultado = carrinho.map2(paraObjeto).map2(apenasPreco);

console.log(resultado);
  1. Array: Filter #01
const produtos = [
    {nome: 'Notebook',         preco: 2000 , fragil: true},
    {nome: 'Ipad Pro',         preco: 5000 , fragil: true},
    {nome: 'Copo de vidro',    preco: 1 ,    fragil: false},
    {nome: 'copo de plastico', preco: 4 , fragil: false},
    {nome: 'copo de vidro',    preco: 5 , fragil: true},
    {nome: 'celular',          preco: 1000 , fragil: true},
]

console.log(produtos.filter(function (p) {
    return false;
}));

const caro   = produto => produto.preco >= 500;
const fragil = produto => produto.fragil;

console.log(produtos.filter(caro).filter(fragil));
  1. Array: Filter #02
Array.prototype.filter2 = function (callback) {
    const newArray = [];
    for (let i = 0; i < this.length; i++) {
        if (callback(this[i], i, this)) {
            newArray.push(this[i])
        }
    }
    return newArray

};

const produtos = [
    {nome: 'Notebook',         preco: 2000 , fragil: true},
    {nome: 'Ipad Pro',         preco: 5000 , fragil: true},
    {nome: 'Copo de vidro',    preco: 1 ,    fragil: false},
    {nome: 'copo de plastico', preco: 4 , fragil: false},
    {nome: 'copo de vidro',    preco: 5 , fragil: true},
    {nome: 'celular',          preco: 1000 , fragil: true},
]

const caro   = produto => produto.preco >= 500;
const fragil = produto => produto.fragil;

console.log(produtos.filter2(caro).filter2(fragil));
  1. Array: Reduce #01
const alunos = [
    {nome: 'jose', nota: 10, bolsista: false},
    {nome: 'maria', nota: 5, bolsista: false},
    {nome: 'carlos', nota: 7, bolsista: true},
    {nome: 'fabio', nota: 4, bolsista: false},
    {nome: 'lorena', nota: 9, bolsista: true},
]

console.log(alunos.map(a => a.nota));

const resultado = alunos.map(a => a.nota).reduce(function (acumulador, atual) {
    console.log(acumulador, atual);
    return acumulador + atual
}, 0); // valor inicial do acumulador

console.log(resultado)
/*
[ 10, 5, 7, 4, 9 ]
0 10
10 5
15 7
22 4
26 9
35
*/
  1. Array: Reduce #02
const alunos = [
    {nome: 'jose', nota: 10, bolsista: false},
    {nome: 'maria', nota: 5, bolsista: false},
    {nome: 'carlos', nota: 7, bolsista: true},
    {nome: 'fabio', nota: 4, bolsista: false},
    {nome: 'lorena', nota: 9, bolsista: true},
]

// Desafio 1: todos os alunos são bolsistas?

const todosBolsistas = (resultado, bolsistas) => resultado && bolsistas
console.log(alunos.map(a => a.bolsista).reduce(todosBolsistas)); // false

// Desafio 2: Algum aluno é bolsista?
const algumBolsistas = (resultado, bolsista) => resultado || bolsista;
console.log(alunos.map(a => a.bolsista).reduce(algumBolsistas))// true
  1. Array: Reduce #03
Array.prototype.reduce2 = function (callback, valorInicial) {
    const indiceInicial = valorInicial ? 0 : 1;
    let acumulador = valorInicial || this[0]

    for (let i = indiceInicial; i < this.length; i++) {
        acumulador = callback(acumulador, this[i], i, this);
    }
    return acumulador;
};

const soma = (total, valor) => total + valor;
const numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(numeros.reduce2(soma, 10));

//
  1. ESNext: Revisão #01
// let e const
{
    var a = 10 // global

    let b = 30 // bloco
    console.log(b)
}
console.log(a)
//console.log(b) //  b is not defined

//Template String
const produto = 'iPad';
console.log(`${produto} é CARO!`);

//Destructuring
const [l, e, ...tras] = 'TESTE';
console.log(l, e, tras); // T E [ 'S', 'T', 'E' ]

const [x, y, z] = [1, 2, 3];
console.log(x,y) // 1 2

const {idade: i, nome} = {nome: 'ANA' , idade: 23};
console.log(i, nome); // 23 ANA
  1. ESNext: Revisão #02
// Arrow function
const soma = (a, b) => a + b;
console.log(soma(2,3))

// Arrow FUnction (this)
const lexico1 = () => console.log(this === exports); // true
const lexico2 = lexico1.bind({}); // true
lexico1()
lexico2();

// param default
function log(texto = 'Node') {
    console.log(texto);
}

log(); // Node
log(undefined);// Node
log(null);// null
log('MUDOU'); // MUDOU

// operador rest

function total(...numeros) {
    let total = 0
    numeros.forEach(n => total += n);
    return total;
}

console.log(total(2, 4, 6));
  1. ESNext: Revisão #03
// ES8: Object. values / Object.entries
const obj = {a: 1, b: 2, c: 3}
console.log(Object.values(obj)) //     [ 1, 2, 3 ]
console.log(Object.entries(obj))//     [ [ 'a', 1 ], [ 'b', 2 ], [ 'c', 3 ] ]


//Melhorias na Notação Literal
const nome = 'JOSE';
const pessoa = {
    nome,
    ola() {
        return "Olá!"
    }
}
console.log(pessoa.nome, pessoa.ola()); // JOSE Olá!

//class
class Animal {

}

class Cachorro extends Animal {
    falar(){
        return 'Au au au ';
    }
}

console.log(new Cachorro().falar()); // Au au au
  1. ESNext: Operador Rest/Spread
// Oeprador ... rest(juntar)/Spread (espalhar)
// usar rest com parâmetros de função

//usar spread com objeto
const funcionario = {nome: 'Maria', salario: 20000}
const clone = {ativo: true, ...funcionario};
console.log(clone); // { ativo: true, nome: 'Maria', salario: 20000 }


// usar spread com array
const grupoA = ['João', 'Pedro', 'Goria'];
const grupoFinal = ['Maria', ...grupoA, 'Rafaela'];

console.log(grupoFinal); // [ 'Maria', 'João', 'Pedro', 'Goria', 'Rafaela' ]
  1. Promises
function falarDepoisDe(segundos, frase) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(frase)
        }, segundos * 1000);
    })
}

falarDepoisDe(3, 'Que Top')
    .then(frase => frase.concat('?!?'))
    .then(outrafrase => console.log(outrafrase))
    .catch(e => console.log(e))
  1. Usando Callbacks Aninhadas
// http://files.cod3r.com.br/curso-js/turmaA.json

const http = require('http')
//sem promise...
const getTurma = (letra, callback) => {
    const url = `http://files.cod3r.com.br/curso-js/turma${letra}.json`
    http.get(url, res => {
        let resultado = ''

        res.on('data', dados => {
            resultado += dados
        })

        res.on('end', () => {
            callback(JSON.parse(resultado));
        })
    })
}

// let nomes = []
// getTurma('A', alunos => {
//     console.log(alunos);
// })

let nomes = [];
getTurma('A', alunos => {
    nomes = nomes.concat(alunos.map(a => `A: ${a.nome}`))
    getTurma('B', alunos => {
        nomes = nomes.concat(alunos.map(a => `B: ${a.nome}`))
        getTurma('C', alunos => {
            nomes = nomes.concat(alunos.map(a => `C: ${a.nome}`))
            console.log(nomes);
        })
    })
})

/*[
  'A: Kellia',   'A: Hi',     'A: Inge',
  'A: Myrle',    'A: Doreen', 'A: Pennie',
  'A: Faye',     'A: Leena',  'A: Taylor',
  'A: Juieta',   'B: Rossie', 'B: Mary',
  'B: Dionysus', 'B: Myca',   'B: Sharlene',
  'B: Meghan',   'B: Perice', 'B: Micheil',
  'B: Nat',      'B: Bone',   'C: Kellina',
  'C: Barrie',   'C: Darda',  'C: Rainer',
  'C: Joan',     'C: Kasper', 'C: Sammie',
  'C: Scott',    'C: Kiel',   'C: Dell'
]
*/
  1. Refatorando Callbacks p/ Promises
// http://files.cod3r.com.br/curso-js/turmaA.json

const http = require('http')
// COM PROMISE...
const getTurma = letra => {
    const url = `http://files.cod3r.com.br/curso-js/turma${letra}.json`

    return new Promise((resolve, reject) => {
        http.get(url, res => {
            let resultado = ''

            res.on('data', dados => {
                resultado += dados
            })

            res.on('end', () => {
                try {
                    resolve(JSON.parse(resultado));
                } catch (e){
                    reject(e);
                }

            })
        })
    } );

}

// let nomes = []
// getTurma('A', alunos => {
//     console.log(alunos);
// })

let nomes = [];
getTurma('A').then( alunos => {
    nomes = nomes.concat(alunos.map(a => `A: ${a.nome}`))
    getTurma('B').then( alunos => {
        nomes = nomes.concat(alunos.map(a => `B: ${a.nome}`))
        getTurma('C').then(alunos => {
            nomes = nomes.concat(alunos.map(a => `C: ${a.nome}`))
            console.log(nomes);
        })
    })
})
/*[
  'A: Kellia',   'A: Hi',     'A: Inge',
  'A: Myrle',    'A: Doreen', 'A: Pennie',
  'A: Faye',     'A: Leena',  'A: Taylor',
  'A: Juieta',   'B: Rossie', 'B: Mary',
  'B: Dionysus', 'B: Myca',   'B: Sharlene',
  'B: Meghan',   'B: Perice', 'B: Micheil',
  'B: Nat',      'B: Bone',   'C: Kellina',
  'C: Barrie',   'C: Darda',  'C: Rainer',
  'C: Joan',     'C: Kasper', 'C: Sammie',
  'C: Scott',    'C: Kiel',   'C: Dell'
]
*/

Promise.all([getTurma('A'), getTurma('B'), getTurma('C')])
    .then(turmas => [].concat(...turmas))
    .then(alunos => alunos.map(aluno => aluno.nome))
    .then(nomes => console.log(nomes))
    .catch(e => console.log(e.message));

Voltar ao Índice


Seção 26: Bonus: HTML Essencial

Voltar ao Índice


About

Curso Vue JS 2 - O Guia Completo (incl. Vue Router & Vuex)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published