O livro "Vue.js em ação"

imagem Oi, habrozhiteli! O objetivo deste livro é fornecer o conhecimento com o qual você não hesitará em ingressar em qualquer projeto usando esta biblioteca. O livro é destinado a todos os interessados ​​em aprender o Vue.js e possui experiência com JavaScript, HTML e CSS. Você não precisa ter um conhecimento profundo dessa área, mas entender o básico, como matrizes, variáveis, loops e elementos HTML, não prejudicará.

Sob o corte, há uma passagem na forma do capítulo Vuex, descrevendo: qual é a condição; o uso de getters; implementação de mutações; adicionando ações; trabalhar com métodos auxiliares do Vuex; módulos e configuração do projeto.

10.1 Por que precisamos do Vuex


A biblioteca Vuex gerencia o estado. Ele é armazenado centralmente, o que facilita o acesso a qualquer componente. Status são informações ou dados que dão suporte ao aplicativo. Isso é importante porque precisamos de um mecanismo confiável e compreensível para trabalhar com essas informações.

Se você já possui experiência em trabalhar com outras estruturas para criar aplicativos de página única, alguns desses conceitos podem parecer familiares. Por exemplo, o React usa um sistema de gerenciamento de estado semelhante chamado Redux. Vuex e Redux são influenciados pelo projeto Flux. Essa é a arquitetura proposta pelo Facebook, projetada para simplificar a construção de aplicativos Web clientes. Contribui para a movimentação de dados em uma direção: das ações para o expedidor, depois para o armazenamento e, no final, para a visualização. Essa abordagem permite separar o estado do restante do aplicativo e incentiva as atualizações síncronas. Você pode aprender mais sobre o Flux na documentação oficial em facebook.imtqy.com/flux/docs/overview.html.

O Vuex trabalha com o mesmo princípio, ajudando a mudar de estado de forma previsível e síncrona. Os desenvolvedores não precisam se preocupar com as conseqüências da atualização do estado com funções síncronas e assíncronas. Imagine que estamos interagindo com uma API do servidor que retorna dados no formato JSON. O que acontece se, ao mesmo tempo, esses dados forem modificados por uma biblioteca de terceiros? Não queremos um resultado imprevisível. O Vuex ajuda a evitar tais situações, eliminando quaisquer alterações assíncronas.
Você provavelmente está se perguntando por que precisamos da biblioteca Vuex. No final, o Vue.js permite passar informações aos componentes. Como você sabe nos capítulos anteriores, os parâmetros de entrada e os eventos do usuário são destinados a isso. Poderíamos até criar nosso próprio barramento de eventos para transferência de dados e comunicação entre componentes. Um exemplo de tal mecanismo é apresentado na Fig. 10.1

Isso seria apropriado para pequenas aplicações com um punhado de componentes. Nesse caso, você precisa transferir informações para apenas alguns destinatários. Mas e se o aplicativo for maior, mais complexo e em camadas? É claro que em um projeto grande não é tão fácil acompanhar todas as funções de retorno de chamada, parâmetros de entrada e eventos.

Apenas para essas situações, a biblioteca Vuex foi criada. Ele permite que você organize o trabalho com o estado na forma de um repositório centralizado. Imagine um cenário que vale a pena pensar em usar o Vuex. Por exemplo, estamos trabalhando em um blog com artigos e comentários que você pode criar, editar e excluir. Ao mesmo tempo, temos um painel de administração que permite bloquear e adicionar usuários.

Vamos ver como isso é implementado usando o Vuex. Na fig. A Figura 10.2 mostra que o componente EditBio é filho do painel de administração. Ele precisa acessar as informações do usuário para poder atualizá-las. Trabalhando com o Vuex, podemos acessar o repositório central, modificar os dados e salvar as alterações diretamente do componente EditBio. Isso é muito melhor do que passar informações da instância raiz do Vue.js para o componente Admin e depois para o EditBio usando os parâmetros de entrada. Seria difícil para nós acompanhar dados localizados em lugares diferentes.

imagem

imagem

No entanto, o uso do Vuex tem um preço na forma de código adicional padrão e complexidade da estrutura do aplicativo. Como já mencionado, é melhor não usar essa biblioteca em projetos simples que consistem em vários componentes. Seu potencial real se manifesta em grandes aplicações com um estado mais complexo.

10.2 Estado e mutação em Vuex


O Vuex armazena o estado de todo o aplicativo em um único objeto, também chamado de fonte única de verdade. Como o nome sugere, todos os dados são coletados em um único local e não são duplicados em outras partes do código.
DICA

Vale ressaltar que não somos obrigados a armazenar todos os nossos dados no Vuex. Componentes individuais podem ter seu próprio estado local. Em certas situações, isso é preferível. Por exemplo, seu componente tem uma variável que é usada apenas dentro dele. Ela deve permanecer local.
Considere um exemplo simples de como trabalhar com o estado no Vuex. Todo o nosso código será colocado em um arquivo. Mais tarde, você aprenderá como adicionar o Vuex a um projeto usando o Vue-CLI. Abra um editor de texto e crie o arquivo vuex-state.html. Iremos exibir uma mensagem localizada no repositório central e um contador. O resultado é mostrado na fig. 10.3

imagem Primeiro, adicione tags de script com links para o Vue e o Vuex. Em seguida, crie a marcação HTML. Usaremos as tags H1, H2, H3 e o botão. A tag h1 exibe o cabeçalho com uma variável local declarada na instância Vue.js. As mensagens de boas-vindas e de contador são executadas como propriedades calculadas com base no repositório Vuex.

O elemento button aciona uma ação de incremento. Copie o código da Listagem 10.1 no arquivo vuex-state.html.

imagem

Quando você terminar a marcação HTML, vamos começar a criar o repositório Vuex. Ele conterá todos os dados do aplicativo, incluindo as propriedades msg e count.

Para atualizar o estado, usamos mutações. Isso é algo como setters de outras linguagens de programação. O setter define o valor, a mutação atualiza o estado do programa. No Vuex, as mutações devem ser síncronas. Em nosso exemplo, o contador é incrementado apenas com o clique de um botão, portanto, não há necessidade de se preocupar com código assíncrono (mais tarde, consideraremos ações que ajudam a resolver problemas com assincronia).

Crie uma função de incremento dentro do objeto de mutações que incrementa o estado. Pegue o código na Listagem 10.2 e cole-o na parte inferior do arquivo vuex-state.html.

imagem

Então, preparamos a marcação HTML e o repositório Vuex. Agora você pode adicionar uma lógica que os conectará. Queremos que o modelo exiba os valores de msg e contador, que fazem parte do estado Vuex. Além disso, o contador precisa ser atualizado.

Crie uma instância do Vue.js com uma nova função de dados que retornará uma propriedade de cabeçalho local com o texto do aplicativo Vuex. Na seção computada, adicione as propriedades calculadas bem-vindo e contador. O primeiro retornará store.state.msg e o segundo - store.state.count.

Por fim, você precisa adicionar um método chamado incremento. Uma mutação foi declarada no repositório Vuex, mas não podemos usá-la diretamente para atualizar o estado. Uma função de confirmação especial é fornecida para isso. Ele diz ao Vuex para atualizar o repositório e, assim, salvar as alterações. A expressão store.commit ('incremento') executa a mutação. Insira o seguinte snippet (Listagem 10.3) imediatamente após o código criado na Listagem 10.2.

imagem

Este é um aplicativo de trabalho completo baseado no Vuex! Tente pressionar o botão - cada vez que você pressiona o contador deve aumentar em 1.

Atualize o código para que pressionar o botão aumente o contador em 10. Se você observar atentamente a mutação do incremento, perceberá que são necessários apenas um argumento, estado. Vamos passar outro - vamos chamá-lo de carga útil. Será transmitido pelo método increment, criado na instância raiz do Vue.js.

Copie o conteúdo de vuex-state.html para o novo arquivo vuex-state-pass.html. Usando este aplicativo como exemplo, mostramos como os argumentos são passados.

Como você pode ver na Listagem 10.4, apenas o objeto de mutações e o método de incremento precisam ser atualizados. Adicione ao incremento da mutação outro argumento chamado carga útil. Esse é o valor pelo qual state.count aumentará. Localize a chamada para store.commit dentro do método de incremento e especifique 10 como o segundo argumento. Atualize o arquivo vuex-state.html como mostrado abaixo.

imagem

Salve o arquivo vuex-state-pass.html e abra-o em um navegador. Agora, quando o botão é pressionado, o contador deve aumentar em 10 e não em 1. Se algo der errado, verifique o console do navegador e verifique se não há erros de digitação.

10.3 Getters e ações


No exemplo anterior, acessamos a loja diretamente a partir das propriedades calculadas. Mas e se tivéssemos vários componentes que precisassem do mesmo acesso? Suponha que desejamos exibir uma mensagem de boas-vindas em letras maiúsculas. Nesse caso, os getters nos ajudarão.

Getters fazem parte da Vuex. Eles permitem implementar o acesso unificado ao estado em todos os componentes. Vamos dar um exemplo da seção 10.2 e, em vez de acesso direto ao repositório através de propriedades calculadas, usamos getters. Além disso, fazemos com que o getter da propriedade msg traduza todas as suas letras para maiúsculas.

Copie o conteúdo do arquivo vuex-state-pass.html para vuex-state-getter-action.html. Para simplificar a tarefa, deixe o código HTML inalterado. No final, você deve obter algo semelhante ao da fig. 10.4

imagem Como você pode ver, a mensagem Hello World agora é exibida em palavras. Pressionar o botão Press Me aumenta o contador da mesma maneira que no exemplo anterior.

Localize a construção Vuex.Store dentro do novo arquivo vuex-state-getter-action.html imediatamente abaixo da tag imagem Adicione um novo objeto após mutações chamadas getters. Crie os métodos msg e count dentro deste objeto, conforme mostrado na Listagem 10.5. Ambos os métodos aceitam o mesmo argumento de estado.

O msg getter retornará state.msg.toUppercase (). Graças a isso, a mensagem é sempre exibida em maiúsculas. No get getter, retornaremos state.count. Depois de adicionar getters abaixo das mutações, o arquivo vuex-state-getter-action.html deve ficar assim.

imagem

Ações são outra parte integrante da Vuex. Eu mencionei anteriormente que as mutações devem ser síncronas. Mas e se trabalharmos com código assíncrono? Como fazer chamadas assíncronas capazes de mudar de estado? As ações da Vuex nos ajudarão nisso.
Imagine que o aplicativo esteja acessando o servidor e aguardando uma resposta. Este é um exemplo de uma ação assíncrona. Infelizmente, as mutações são assíncronas, portanto não podemos usá-las aqui. Em vez disso, adicione uma operação assíncrona com base na ação Vuex.

Para criar um atraso, use a função setTimeout. Abra o arquivo vuex-state-getter-action.html e adicione o objeto de ações imediatamente após os getters. Dentro deste objeto, coloque a ação de incremento, que recebe os argumentos de contexto e carga útil. Usando o contexto, salvaremos as alterações. Coloque a operação context.commit dentro de setTimeout. Dessa forma, simulamos um atraso no servidor. Também podemos passar o argumento de carga útil para context.commit, que entra na mutação. Atualize o código com base na Listagem 10.6.

Após atualizar o Vuex.Store, você pode prosseguir para a instância raiz do Vue.js. A propriedade computada não acessará a loja diretamente, como antes, mas usando getters. Também estamos modificando o método de incremento. Para acessar a nova propriedade Vuex que criamos anteriormente, ela usará a chamada store.dispatch ('increment', 10).

imagem

O primeiro argumento para a chamada de despacho é o nome da ação e o segundo argumento sempre contém dados adicionais que são passados ​​para essa ação.
DICA

Dados adicionais podem ser uma variável regular ou até um objeto.
Atualize a instância Vue.js no arquivo vuex-state-getter-action.html, como mostra a Listagem 10.7.
imagem

Baixe o aplicativo e pressione o botão várias vezes. Você deve notar um atraso, mas o contador aumentará em 10 após cada pressionamento.

10.4 Usando o Vuex em um projeto de pet shop usando o Vue-CLI


Vamos voltar ao projeto da loja de animais em que estávamos trabalhando. Se você não esqueceu, decidimos adicionar animações e transições. Agora integramos a biblioteca Vuex que conhecemos anteriormente.

Transferimos os dados das mercadorias para o armazém. Como você se lembra dos capítulos anteriores, os dados foram inicializados no gancho criado dentro do componente Principal. Agora esse gancho deve gerar um novo evento que inicializa o repositório Vuex. Também adicionaremos os produtos calculados da propriedade, que recuperam produtos usando o getter (criaremos mais tarde). O resultado final será semelhante na Fig. 10.5

imagem

10.4.1 Instale o Vuex com o Vue-CLI


Primeiro, instale o Vuex! Este é um processo simples. Prepare a versão mais recente da pet shop em que trabalhamos no capítulo 8. Você também pode baixar todo o código deste capítulo no GitHub em github.com/ErikCH/VuejsInActionCode.

Abra uma janela do terminal e vá para o diretório raiz do projeto. Para instalar a versão mais recente do Vuex, execute o seguinte comando:

$ npm install vuex 

e salve o registro no arquivo package.json da pet shop.

Agora você precisa adicionar o armazenamento ao arquivo main.js, localizado na pasta src. O repositório em si ainda não existe, mas nós o importamos de qualquer maneira. Geralmente, ele está no arquivo src / store / store.js, mas você pode escolher um caminho diferente - todos os desenvolvedores têm suas próprias preferências. Vamos nos debruçar sobre a opção geralmente aceita. Mais adiante neste capítulo, discutiremos uma estrutura de diretórios alternativa usando módulos.

Você precisa adicionar armazenamento à instância raiz do Vue.js abaixo do roteador, conforme mostrado na Listagem 10.8. A propósito, usamos o padrão ES6, portanto, store: store pode ser reduzido para armazenar.

imagem

Após conectar o armazenamento à instância raiz, podemos acessá-lo em qualquer parte do aplicativo. Crie o arquivo src / store / store.js. Nele, colocaremos o repositório Vuex com informações sobre os produtos oferecidos pela pet shop. Na parte superior, adicione duas instruções de importação, uma para o Vue e o Vuex. Em seguida, especifique Vue.use (Vuex) para juntar tudo.

Importamos o repositório no arquivo main.js. de ./store/store. Agora você precisa exportar o objeto de loja dentro de store.js. Como você pode ver na Listagem 10.9, exportamos um valor de armazenamento const igual a Vuex.Store.

Primeiro, adicione objetos com estado e mutações. O estado conterá um objeto vazio chamado produtos. Em breve iremos preenchê-lo com o método initStore. A mutação é chamada SET_STORE, atribuirá os bens transferidos à propriedade state.products. Cole o código da lista a seguir no arquivo src / store / store.js que acabamos de criar.

imagem

Precisamos criar uma ação e getter no repositório. Um getter retornará um objeto de produtos. A ação é um pouco mais complicada. Você deve transferir o gancho criado, que lê o arquivo static / products.json usando o Axios, para o objeto de ações no Vuex.

Mencionei anteriormente que as mutações devem ser síncronas e que somente as ações dentro do Vuex podem aceitar código assíncrono. Para contornar essa limitação, coloque o código Axios na ação Vuex.

Crie um objeto de ações no arquivo store.js e inclua o método initStore. Copie o conteúdo do gancho criado do arquivo components / Main.vue para este método. Em vez de atribuir response.data.products ao objeto products, invocamos a mutação usando a função commit. Passe response.data.products como argumento para SET_STORE. O código resultante deve se parecer com isso (Listagem 10.10).

imagem

Estamos quase terminando, basta atualizar o arquivo Main.vue e transferir as mercadorias do objeto de produtos locais para o repositório Vuex. Abra o arquivo src / components / Main.vue e localize a função de dados. Remova os produtos de linha: {}. Acessaremos as mercadorias a partir da propriedade computada que a loja retorna.

Localize as propriedades calculadas cartItemCount e selectedProducts dentro de Main.vue, eles devem ir logo após a seção de métodos. Inclua a propriedade products e faça com que ela retorne o getter com o mesmo nome.

Conectamos o repositório à instância raiz do Vue.js no arquivo main.js. Portanto, não precisamos mais importá-lo. Além disso, ao usar o Vue-CLI, o armazenamento está sempre disponível no formato. $ Store. Não esqueça o sinal de $, caso contrário, isso resultará em um erro. Adicione a propriedade de produtos computados, conforme mostrado na Listagem 10.11.

imagem

Encontre o gancho criado no qual o objeto de produtos é inicializado e exclua seu conteúdo. Em vez disso, insira a chamada de ação initStore que criamos anteriormente no repositório Vuex. Para chamar uma ação, use a função de despacho, como no exemplo anterior. A Listagem 10.12 mostra a aparência do gancho criado após a atualização do arquivo Main.vue.

imagem

Isso deve ser o suficiente. Execute o comando npm run dev no terminal e uma janela com o aplicativo pet store deve aparecer na tela. Tente colocar as mercadorias na cesta e verifique se tudo funciona como deveria. Se algo der errado, procure por erros no console. No arquivo src / store / store.js, em vez de Vuex.store, você pode digitar acidentalmente Vuex.Store. Lembre-se disso!

10.5 Métodos auxiliares Vuex


O Vuex fornece métodos auxiliares convenientes que tornam o código mais conciso e eliminam a adição dos mesmos getters, setters, mutações e ações. Para obter uma lista completa dos métodos auxiliares do Vuex, consulte o guia oficial em vuex.vuejs.org/guide/core-concepts.html. Vamos ver como eles funcionam.

O principal método auxiliar que você deve conhecer é chamado mapGetters. É usado para adicionar todos os getters disponíveis à seção computada e não requer a listagem de cada um deles. Mas antes de usá-lo, você precisa importá-lo dentro do componente. Mais uma vez, volte para a loja de animais e adicione o método mapGetters.

Abra o arquivo src / components / Main.vue e localize a tag de script. Em algum lugar dessa tag, o componente Cabeçalho deve ser importado. Conecte mapGetters imediatamente após essa importação, conforme mostrado na Listagem 10.13.

imagem

Agora você precisa atualizar a propriedade computada. Encontre a função de produtos na seção computada e insira o objeto mapGetters em seu lugar.

mapGetters é um objeto exclusivo; para sua operação correta, é necessário usar o operador de spread do ES6 - ele expande a expressão em uma situação em que qualquer argumento é esperado (zero ou mais). Você pode ler mais sobre essa sintaxe na documentação do MDN em developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Spread_syntax .

mapGetters garantirá que todos os getters sejam adicionados como propriedades calculadas. Essa é uma maneira muito mais simples e elegante do que escrever uma propriedade computada separada para cada getter. Todos os getters estão listados na matriz mapGetters. Adicione este método auxiliar ao arquivo Main.vue (Listagem 10.14).

imagem

Após executar o comando npm run dev, a loja de animais deve funcionar como antes. O método auxiliar mapGetters não parece muito útil até agora, mas quanto mais getters adicionarmos, mais tempo ele economizará.

Existem mais três métodos auxiliares que você deve conhecer: mapState, mapMutations e mapActions. Todos eles funcionam de maneira semelhante, reduzindo a quantidade de código padrão que você precisa escrever manualmente.

Imagine que seu repositório contenha várias partes de dados e o acesso ao estado seja realizado diretamente a partir do componente, sem o uso de getters. Nesse caso, você pode usar o método mapState dentro da seção computada (Listagem 10.15).

imagem

Agora imagine que você precisa usar várias mutações em um componente. Para simplificar esse processo, use o método auxiliar mapMutations (Listagem 10.16), como é feito com mapState e mapGetters. Em seguida, mut1 liga this.mut1 () a isso. $ Store.commit ('mut1').

imagem

Por fim, considere o método auxiliar mapActions. Permite adicionar ações Vuex ao aplicativo, eliminando a necessidade de criar métodos com chamadas de despacho em cada caso. Voltando ao exemplo anterior, imagine que o aplicativo contenha algumas operações assíncronas. Como o uso de mutações é excluído, devemos recorrer à ação. Depois de criá-los no Vuex, você precisa acessá-los no objeto de métodos do componente. Esse problema pode ser resolvido usando mapActions. act1 ligará this.act1 () a isso. $ store.dispatch ('act1'), conforme mostrado na Listagem 10.17.

imagem

Por fim, considere o método auxiliar mapActions. Permite adicionar ações Vuex ao aplicativo, eliminando a necessidade de criar métodos com chamadas de despacho em cada caso. Voltando ao exemplo anterior, imagine que o aplicativo contenha algumas operações assíncronas. Como o uso de mutações é excluído, devemos recorrer à ação. Depois de criá-los no Vuex, você precisa acessá-los no objeto de métodos do componente. Esse problema pode ser resolvido usando mapActions. act1 ligará this.act1 () a isso. $ store.dispatch ('act1'), conforme mostrado na Listagem 10.17.

imagem

À medida que o aplicativo cresce, esses métodos auxiliares serão cada vez mais úteis, reduzindo a quantidade de código que precisa ser gravada. Lembre-se de que você precisa pensar nos nomes das propriedades em seu repositório, pois os métodos auxiliares permitem que você os acesse nos componentes.

10.6 Breve introdução aos módulos


No início deste capítulo, criamos o arquivo store.js no diretório src / store. Para um projeto pequeno, essa abordagem é bastante apropriada. Mas e se estivermos lidando com um aplicativo muito maior? O arquivo store.js aumentará rapidamente e será difícil acompanhar tudo o que acontece nele.
Para resolver esse problema, a Vuex oferece o conceito de módulos. Os módulos permitem dividir o armazenamento em várias partes menores. Cada módulo tem seus próprios estados, mutações, ações e getters, você pode até torná-los aninhados um no outro.

Reescrevemos a loja de animais usando módulos. O arquivo store.js permanecerá no local, mas ao lado dele, você deve criar a pasta modules e colocar o arquivo products.js lá. A estrutura de diretórios deve se parecer com a da fig. 10.6

imagem Dentro do products.js, você precisa criar quatro objetos: estado, getters, ações e mutações. O conteúdo de cada um deles deve ser copiado do arquivo store.js.

Abra o arquivo src / store / store.js e comece a copiar o código dele. Quando concluído, o arquivo products.js deve se parecer com isso (Listagem 10.18).

Agora precisamos exportar todo o código que adicionamos ao arquivo product.js. Isso irá importá-lo para o store.js. Na parte inferior do arquivo, adicione a expressão padrão de exportação. Esta é uma instrução de exportação no formato ES6 que permite importar esse código de outros arquivos (Listagem 10.19).

O arquivo store.js deve ser atualizado. Adicione um objeto de módulos a ele, dentro do qual você poderá listar todos os novos módulos. Lembre-se de importar o arquivo de módulos / produtos que criamos anteriormente.

imagem

Nosso exemplo contém apenas um módulo, então adicione-o imediatamente ao objeto modules. Você também precisa remover todos os itens desnecessários do Vuex.Store, conforme mostrado na Listagem 10.20.

imagem

Ao importar os módulos, concluímos o processo de refatoração. Após atualizar a página, o aplicativo deve funcionar exatamente como antes.
Namespaces no Vuex

Em alguns projetos grandes, a modularização pode causar certos problemas. À medida que novos módulos são adicionados, podem surgir conflitos com os nomes de ações, getters, mutações e propriedades de estado. Por exemplo, você pode atribuir acidentalmente o mesmo nome a dois getters em arquivos diferentes. E, como tudo está em um espaço de nomes global global no Vuex, ocorrerá um erro de chave duplicada no console.
Para evitar esse problema, coloque cada módulo em um espaço para nome separado. Para fazer isso, basta especificar namespaced: true na parte superior do Vuex.store. Leia mais sobre esse recurso na documentação oficial da Vuex em vuex.vuejs.org/en/guide/modules.html.
»Mais informações sobre o livro podem ser encontradas no site do editor
» Conteúdo
» Trecho

Cupom de 25% para vendedores ambulantes - Vue.js

Após o pagamento da versão em papel do livro, uma versão eletrônica do livro é enviada por e-mail.

Source: https://habr.com/ru/post/pt448304/


All Articles