Photo by Yancy Min on Unsplash

Como estruturar vuex, vue js app e axios com modules

João Nascimento
9 min readAug 20, 2020

--

Guia de estrutura de aplicação Vuex

Nota: preste atenção à palavra em negrito.
Embora o Vuex não restrinja a estrutura do seu código, existem algumas maneiras fáceis de melhorar a qualidade do seu código, não se perca no código.

O primeiro princípio é centralizado na loja.

A única maneira de alterar o estado é por commit ou actions, mutações, que são transações síncronas.
A lógica assíncrona deve ser encapsulada e pode ser composta com ações.
Contanto que você siga essas regras, depende de você como estruturar seu projeto. Se o arquivo da sua store for muito grande, basta começar a dividir as actions, mutations e getters em arquivos separados com módulos.

Aqui está um exemplo de uma estrutura de projeto:

Em primeiro lugar, você precisa entender a Gestão Estadual da Vuex.
Vuex são divididos em partes:

State — onde o estado das variáveis ​​é armazenado
View — visualizar um mapeamento de estado de declaração, para acessar o estado com getters indiretamente
Actions — para mudar um estado

Quando você começar a ter vários componentes que compartilham um estado comum, aumente rapidamente a complexidade.
Por exemplo, você tem múltiplas visualizações, cada uma delas altera o estado de uma variável, então se você tiver uma variável de contagem, uma visualização adiciona uma e a outra diminui em um, essas ações precisam estar atualizando o mesmo estado.

Isso parece simples, passando propriedades (adereços) para componentes aninhados, componentes pai e filho, mas se os componentes não são pai e filho, eles são componentes irmãos, isso significa que as visualizações aparecem ao mesmo tempo, se você diminuir um, eles atualizam a visão do outro.

A solução é o Vuex, o Vuex extrai o estado compartilhado dos componentes e o gerencia em um singleton global.

O Vuex ajuda a compartilhar o gerenciamento de estado, mas com um custo de código mais repetitivo. Mesmo em projetos simples, eu uso vuex porque um projeto simples tende a se tornar mais complexo em desenvolvimentos futuros.

Como funciona o vuex ??

Veja o diagrama a seguir, como uma citação de Dan Abramov

“Flux libraries are like glasses: you’ll know when you need them.”

Agora, se você começar a fazer um arquivo de armazenamento grande, você desejará dividir em arquivos pequenos, talvez divididos por modelos. Você precisará de Módulos.

O que são Módulos e como funcionam ??

No entanto, a medida que o nosso aplicativo cresce, a store pode ficar realmente grande.
Vuex nos permite usar módulos. Cada módulo pode conter seu próprio estado, mutação, ação, getters e até mesmo outros módulos.

Ações, mutações e getters em módulos ainda são registrados no namespace global, o que permite que vários módulos reajam ao mesmo tipo de ação ou mutação.

Exemplo de loja com módulos.

Como você pode ver, é fácil dividir e entender a lógica por trás desses módulos.

Quando você chama uma mutação, se você tem nomes diferentes, é importante para a não colisão, você chama assim:
O vuex sabe que a bruxa está sendo chamada. E mude o estado deles.
Se você tiver um getter na visualização, o vuex atualizará automaticamente essas visualizações.

Quando um componente precisa fazer uso de várias propriedades de estado de armazenamento, declarar esses dados computados pode ser repetitivo e prolixo.

Para nos ajudar com isso, podemos usar o helper mapState, que gera funções getter computadas para nós, salvando algumas linhas de código.

No entanto, para usá-lo com outros dados locais, teríamos que usar um utilitário para juntar vários objetos em um para passar o objeto final para o computed.

Para simplificar, usamos o Spread Operator, deixando nosso mapeamento de estado da seguinte forma:

mapState

Observe que, como primeiro parâmetro, passamos o nome do módulo e, em seguida, um array com os estados que serão mapeados para nosso componente.

Lembrando que, embora estejamos usando Vuex, isso não significa que você deva deixar tudo no estado Vuex. Isso é importante!!!

Embora colocar mais estado em Vuex torne suas mutações de estado mais explícitas e depuráveis.

Como depurar vuex, se você usar o google chrome, você apreciará esta extensão.

Por exemplo, se um pedaço de estado pertence estritamente a um único componente, pode ser bom deixá-lo apenas como um estado local.
Vamos falar sobre Getters

Filtrando com getter, para isso você pode usar como o seguinte:

Usando este estado, você pode chamar o getter assim:

Filtrar por uma lista de itens e contá-los.
Agora dê uma olhada no componente principal

Mapeamos nosso getter quase da mesma maneira que fizemos com o estado, no entanto, agora usando mapGetters e o renderizamos em nosso DOM.

E, finalmente, nosso aplicativo mostra o resultado renderizado.

Mutações

Mutações é a única maneira de chamar para alterar um estado. Embora as mutações pareçam muito semelhantes às ações: cada mutação tem uma string de tipo e um manipulador.

É um padrão comumente usado para usar constantes para tipos de mutação em várias implementações.

Vamos construir duas mutações: uma para aumentar nosso estado de contagem e outra para diminuir. Nosso arquivo de mutação dentro do diretório store / module-example terá a seguinte aparência:

As mutações também podem receber um argumento adicional denominado carga útil. Na maioria dos casos, a carga útil é um objeto que contém informações (por exemplo, uma resposta da API) a serem repassadas ao estado.

Agora, em nosso componente principal, adicionamos dois botões e o mapMutation para alterar o estado de contagem.

Nosso aplicativo agora possui dois botões que alteram o estado de nosso contador.

Aplicativo com contador de incremento e decremento
No Vuex, as mutações são transações síncronas.

E como devo lidar com operações assíncronas?

A resposta é com ações.

As ações são semelhantes às mutações. As diferenças são as seguintes: em vez de alterar o estado, as ações confirmam (ou confirmam) as mutações, você deve chamar as ações e a mutação na chamada da ação.

As ações podem conter operações assíncronas arbitrárias.

Observe que simulamos operações assíncronas em nossas ações adicionando um pequeno atraso com setTimeout. Substituímos as mutações em Index.vue por ações e modificamos nossos botões para acioná-las.

Ao clicar nos botões de incremento e decremento, leva um segundo para o estado de contagem mudar.

Mas onde está a gestão do estado global?

Por enquanto, vimos apenas a mudança de estado em uma única visualização. No entanto, vamos agora fazer um exemplo para que possamos ver mais claramente como todo esse gerenciamento é feito separadamente do estado local dos componentes Vue.

Primeiro, vamos criar um componente vue, com dois outros botões de incremento e decremento. No diretório de componentes, criamos o arquivo CButtons.vue.

Nesses componentes, usaremos a mesma lógica de incremento e decremento que usamos em Index.vue com o mapeamento de ações:

Na página Index.vue importamos nosso componente e o registramos:

O resultado agora é nossa página Index.vue com quatro botões, dois dos quais estão no HTML do próprio Index.vue, e os outros dois do componente CButtons importado.

Normalmente, para poder trocar informações entre os componentes pai / filho, adereços e eventos eram necessários. Porém, com a Vuex podemos acessar a loja de qualquer lugar em nosso aplicativo.

Agora o problema de axios (respostas http) e armazenar quando você inicializa um componente

Seguindo nosso exemplo, se você precisa armazenar o aumento e a diminuição de um estado em um Banco de Dados ??

Como eu devo fazer???

Geralmente, nossos componentes recebem estados e ações Vuex por meio da propriedade vuex no componente, como este:
Component.vue

Esta é a estrutura básica de como obter as propriedades armazenadas na loja e suas mutações (ações).

Mas … Se você deseja ter um serviço de autenticação independente de componente, ou seja, que esteja contido em um arquivo e que consulte o armazenamento diretamente, sem a necessidade de encapsulá-lo em um componente como no código acima.

Se você pesquisar na Internet fora, verá muitos exemplos como o código acima, e na própria documentação do Vuex se parece com este. Outra parte do código comum que você encontra para inicializar o armazenamento é algo assim:

// store.js

// main.js

Bem … eu já tinha a loja no meu componente App.vue e estava disponível para todos os aplicativos.

Mas e o meu serviço de autenticação (authService)?

Foi então que decidi arriscar e importar a loja para um arquivo chamado index.js dentro de uma pasta chamada authService e voilà !!!! Agora bastou eu importar o authService que tinha acesso ao conteúdo da loja. Mas espere! Não foi pela pasta e muito menos pelos nomes, fiz justamente para organizar o código.

Agora posso ter o serviço da seguinte maneira:

// main.js

//index.js em /vuex/auth

// store.js

E importando authService:

// index.js em /services/authService

Quando preciso usar o serviço de autenticação para escrever o token de algum componente, faço o seguinte: //MyComponent.vue

Como estruturar chamadas de API em Vue.js?

Atualmente, estou trabalhando em um novo Vue.js. Depende muito de chamadas de API para meu banco de dados back-end.

Para muitas coisas, eu uso lojas Vuex porque gerencia dados compartilhados entre meus componentes. Ao olhar para outros projetos Vue no github, vejo um diretório vuex especial com arquivos que lida com todas as ações, estados e assim por diante. Portanto, quando um componente precisa chamar a API, ele inclui o arquivo de ação do diretório vuex.

Mas, para mensagens, por exemplo, não quero usar Vuex porque esses dados só são importantes para uma visualização específica. Quero usar os dados específicos do componente aqui. Mas aqui está o meu problema: ainda preciso consultar minha API. Mas não devo incluir o arquivo de ações da Vuex. Portanto, desta forma, devo criar um novo arquivo de estoque. Dessa forma, tenho um arquivo específico com ações de API para vuex e componentes exclusivos.

Como devo estruturar isso?

Criando um novo diretório ‘api’ que lida com ações para dados vuex e dados específicos de componentes?

Ou separá-lo?

Estou usando axios como um cliente HTTP para fazer chamadas API, criei uma pasta de gateways na minha pasta src e coloquei arquivos para cada back-end, criando instâncias de axios, como seguemyApi.js

Agora, no componente, como podemos obter dados?

Da mesma forma, você pode usar isso para obter dados para sua loja vuex também.

Se você estiver mantendo os dados relacionados ao produto em um módulo vuex dedicado, poderá despachar uma ação de método no componente, que chamará a API de back-end internamente e preencherá os dados na loja, o código terá a seguinte aparência:

Component.vue:

Vue Store code

Estou usando principalmente o recurso Vue. Eu crio o diretório de serviços e coloco todas as conexões nos terminais, por exemplo, PostService.js

SomeView.vue

API de chamada:
Obtendo todos os resultados

--

--