Laravel e Vue.js

Vue.js no Laravel (continuação)

Prosseguindo em nosso estudo do Laravel com Vue.js, nesta continuação iremos trabalhar apenas no arquivo resources\js\components\janela-modal\JanelaModal.vue para realizar melhorias em nosso componente.

Se você ainda não leu o post anterior recomendo que leia primeiro, pois nele são feitas as configurações inciais.
Vue.js no Laravel




Criando a janela modal

Este tutorial foi escrito supondo que o leitor é um total iniciante no Vue.js e, por este motivo, serão apresentados alguns conceitos básicos do framework.

Sobre o Vue.js

No site oficial do Vue.js encontramos a seguinte definição, em tradução livre: Vue.js é um framework progressivo, ou de adoção incremental, para construção de interfaces de usuário.

O que isso quer dizer é que, em contraste com outros frameworks ditos monolíticos, como é o caso do Laravel, em que uma instalação padrão contém diversos elementos mesmo que você não vá utilizá-los; no Vue.js você começa com um conjunto básico de elementos e vai agregando outros se e quando necessitar.

Assim, a instalação básica e inicial do Vue.js, seu núcleo ou core, é composta por uma biblioteca focada apenas na camada de visualização, mas que é facilmente  estendida para integrar com outras bibliotecas ou projetos existentes.

No entanto isto não diminui o poder e a aplicabilidade do Vue, pois usando este framework, em conjunto com outras ferramentas e bibliotecas de suporte, é possível criar sofisticados aplicativos de página única.

Vale lembrar que é possível utilizar o Vue.js sem o Laravel, porém para isto é necessário realizar a instalação manual, conforme descrito no site oficial no link:

https://vuejs.org/v2/guide/installation.html

Contudo se você chegou até aqui, presumo que foi porque leu a primeira parte deste post e, por isto, tem interesse no uso dos frameworks Vue.js e Laravel em conjunto.

Componente

Um componente Vue.js é uma instância reutilizável que possui um nome e que pode ser utilizada como um elemento personalizado dentro de uma instância raiz do Vue.

Em nosso caso, em razão do Laravel já providenciar a criação da instância da aplicação Vue, não precisamos nos preocupar com esta instância dita raiz.

Por enquanto, basta saber que para utilizar um componente no Laravel será necessário incluir as referências ao app.js e app.cs e uma div com id de app, conforme o código das linhas abaixo:

<head>
	...
    <link rel="stylesheet" href="{{ asset('css/app.css') }}">
...
</head>
<body>
	...
    <div id="app">
	<componente></componente>
    </div>
	...
<script src="{{ asset('js/app.js') }}"></script>
	...
</body>

É possível reutilizar um componente quantas vezes você desejar, no exemplo acima, isto poderia ser feito repetindo a linha: <componente></componente> o número de vezes necessário.




Estrutura do componente

Para facilitar nosso entendimento do Vue.js iremos direto ao estudo de um componente e quando for necessário apresentaremos conceitos teóricos a respeito do funcionamento do framework.

Um componente Vue pode ser dividido em três seções: template, script e style. Abaixo uma pequena descrição de cada uma delas:

  • template: é a seção responsável por produzir o código HTML que será gerado pelo componente; como o nome diz contém um template de HTML que será modificado automaticamente pelo Vue.js, fazendo substituições de variáveis e outras operações, para gerar as tags html que serão entregues ao browser para serem renderizadas;
  • script: conterá o código JavaScript responsável pelo comportamento do componente; é nesta seção que serão definidas as propriedades, métodos e atributos do componente;
  • style: nesta seção estão contidas as definições de estilização CSS para o componente; usando o atributo scoped podem ser definidas propriedades para os seletores CSS que serão aplicadas somente aos elementos do componente atual;

Neste texto para explicar o código dos exemplos de componentes iremos adotar esta divisão em seções conforme citado acima.

Lembrando que os componentes também são instâncias do Vue, de forma que eles aceitam as mesmas opções da instância raiz (new Vue), como por exemplo: data, computed, watch, methods e gatilhos de ciclo de vida. As únicas exceções são as poucas opções específicas de raiz, como el.

Template

Continuando a codificação de nosso componente, no arquivo JanelaModal.vue, inclua o código abaixo:

<template>
    <div>
        <div id="myModal" class="modal-win">
            <div class="modal-content">
                <div>
                    <span class="close" @click="closeClick">×</span>
                    <p>
                        <slot>Coloque aqui o texto de sua Janela Modal.</slot>
                    </p>
                </div>
            </div>
        </div>
    </div>
</template>

Esta seção template contém o código que irá gerar as tags HTML produzidas pelo componente. Abaixo segue a explicação do papel desempenhado por algumas destas linhas de código.

<div id="myModal" class="modal-win">

Esta linha define a div que delimitará o conteúdo da janela modal. Além disso, atribui um identificador e uma classe pelos quais esta div será referenciada, respectivamente, pelo código Javascript e pela folha de estilo CSS.

<div class="modal-content">

Neste trecho é definida uma outra div que conterá o texto que será exibido na janela modal. Ela também conterá o X no qual se deverá clicar para que o modal despareça da tela.

<span class="close" @click="closeClick">&times;</span>

Este trecho é responsável por criar o X (representado pelo símbolo especial, ou entidade, HTML &times;). Além disso, define a classe (close) para possibilitar estilização posteriormente; e associa uma função JavaScript (closeClick) ao evento onClick deste elemento, no Vue.js este recurso se chama v-on e nos próximos tópicos veremos com mais detalhes a seu respeito incluindo o porquê do uso do @click.

<slot>Coloque aqui o texto de sua Janela Modal.</slot>

No Vue.js uma definição de slot corresponde a um espaço reservado que será preenchido com conteúdo fornecido pelo usuário do componente. Neste trecho a definição de slot contém um fallback, conteúdo padrão, que será usado caso não seja passado nenhum valor para o componente.

Examinaremos agora com um pouco mais de detalhe os dois conceitos que foram introduzidos acima: v-on e slot.

v-on

Nos componentes do Vue.js é utilizada a diretiva v-on para capturar os eventos do DOM e acionar algum JavaScript quando o evento for disparado.

A sintaxe do comando da diretiva é v-on:[evento], onde o parâmetro [evento] deve ser um evento nativo do DOM. Para consultar quais são estes eventos visite o link abaixo:

https://developer.mozilla.org/pt-BR/docs/Web/Events

É comum utilizar-se o @ como uma forma resumida da diretiva v-on, assim em vez de escrever v-on:click, escreve-se somente @click. Em nosso código exemplo foi utilizada esta notação simplificada.

slot

Recebe o conteúdo que fica entre as tags do componente, caso não haja nenhum slot definido este conteúdo será ignorado pelo Vue.js, veja o exemplo abaixo:

<componente>Este conteúdo será enviado ao slot</componente>

Caso houvesse um slot definido no componente ele receberia a string: Este conteúdo será enviado ao slot, caso contrário este conteúdo seria ignorado.

Usando um slot podem também ser passados ao template códigos, como por exemplo tags HTML, ou até mesmo outros componentes.




Script

Nesta seção iremos definir as propriedades ou atributos e o código JavaScript correspondente aos métodos do componente.

Para fazer isto altere o arquivo JanelaModal.vue e inclua o código abaixo:

<script>
export default {
    methods: {
        //Fecha o modal quando usuário clicar no X		
        closeClick() {
            myModal.style.display = "none";
        },
        //Fecha o modal quando usuário clicar em qualquer lugar na janela do browser
        janelaClick(event) {
            if (event.target == myModal) {
                myModal.style.display = "none";
            }
        }
    },
    created: function() {
        window.addEventListener('click',this.janelaClick);
    },
    destroyed: function() {
        window.removeEventListener('click', this.janelaClick);
    } 
}
</script>

Examinando o código, vemos na seção methods que foram definidos dois métodos. São eles closeClick e janelaClick. Ambos fazem a mesma coisa: esconder a janela modal, sendo a diferença entre eles o elemento disparador do respectivo evento.

O método closeClick será disparado quando o usuário clicar sobre o X na janela modal. No caso de janelaClick será acionado quando o usuário clicar dentro do browser, mas fora da área da janela modal.

Neste momento, a função event.target irá retornar o elemento myModal e, desta forma, o código JavaScript irá definir o valor da propriedade style.display do elemento myModal como none, fazendo com que a janela deixe de ser exibida.

Ciclo de vida

Cada instância Vue, incluindo os componentes, passa por uma série de etapas em sua inicialização – por exemplo, é necessário configurar a observação de dados, compilar o template, montar a instância no DOM, atualizar o DOM quando os dados forem alterados.

Faz parte deste percurso o disparo de alguns gatilhos de ciclo de vida, os quais possibilitam que seja executado código personalizado em etapas específicas deste ciclo.

Voltando ao nosso código temos a seção created que define um destes gatilhos do ciclo de vida da instância do componente Vue.js, na prática esta seção contém código que será executado logo após ser criada uma instância deste componente.

Assim foi utilizado o método addEventListener do elemento de escopo global window para acrescentar o método janelaClick a lista de manipuladores de evento.

Finalizando este código, vemos um outro gatilho do ciclo de vida o destroyed, que contém código que será executado após a instância do componente ser destruída. Sendo seu uso uma boa prática para evitar vazamentos de memória (memory leaks).

Assim, na definição deste gatilho procuramos desfazer o que foi feito na sua contra-parte, ou seja, o created, e usando o método window.removeEventListener, removemos a referência ao método janelaClick que havia sido incluída antes.

Style

O restante do código trata da estilização de nossa janela modal, tendo sido incluídos comentários nas áreas mais relevantes.

Vale mencionar a primeira tag <style scoped> que define um escopo, de forma que as alterações nos atributos dos seletores CSS serão aplicadas apenas nos elementos deste componente.

<style scoped>
    /* Janela Modal (background) */
    .modal-win {
        display: block; /* Exibida por padrao */
        position: fixed; /* Permanece na mesma posicao */
        z-index: 1; /* Sobrepoe os outros elementos */
        left: 0;
        top: 0;
        width: 100%; /* Largura total */
        height: 100%; /* Altura total */
        overflow: auto; /* Habilita o scroll caso necessario */
        background-color: rgb(0,0,0); /* Define cor Fallback */
        background-color: rgba(0,0,0,0.4); /* Define cor Preta/transparencia */
    }

    /* Conteudo da janela Modal */
    .modal-content {
        background-color: #fefefe;
        margin: 15% auto; /* 15% a partir do topo e centralizada */
        padding: 20px;
        border: 1px solid #888;
        width: 80%; /* Pode ser mais ou menos, dependendo do tamanho da tela */
    }

    /* O Botao Fechar */
    .close {
        color: #aaa;
        float: right;
        font-size: 28px;
        font-weight: bold;
    }
</style>

Exibindo o modal

Finalizando, vamos alterar o arquivo resources/views/vue-teste.blade.php e modificar o código original para que fique da forma abaixo:

<janela-modal>Minha primeira janela Modal</janela-modal>

Em seguida, para recompilar o componente, executar o comando:

npm run dev

Caso tudo tenha corrido bem, ao recarregar a página no browser deve ser exibido uma tela semelhante a ilustrada abaixo:

vue-js-componente-janela-moval-v1

Para esconder a janela modal, basta clicar no X ou em qualquer lugar que fique fora do limite do modal na tela do browser.

Se quiser ver o modal novamente poderá recarregar a página.

Finalizamos por enquanto para não ficar cansativo.

No próximo post vamos aprimorar este componente e apresentar alguns novos conceitos do Vue.js segue abaixo o link:

Vue.js no Laravel (conclusão)

Tem alguma sugestão, encontrou algum erro? Deixe seu comentário.
Até a próxima.