Gerenciando estado com Vuex

Como compartilhar estado entre componentes é sempre um desafio, não importa em que arquitetura, framework, ou linguagem está se utilizando.
Em um componente simples, escrito com Vue, é possível armazenar o estado no data(), mas quando você precisa compartilhar este estado entre componentes, começa a dor de cabeça.

É sobre uma das propostas de solução que se trata este texto, também conhecida como arquitetura Flux, altamente inspirada no design pattern singleton. E se você se interessar, pode aprender mais no curso on-line, disponível na Udemy, pagando apenas R$ 75 com o cupom 99DE75.

new Vue({
// estado
data () { return { count: 0 } },
// view
template: ` <div>{{ count }}</div> `,
// ações
methods: { increment () { this.count++ } } }

Caso ainda não tenha tido contato, a maneira natural do Vue trabalhar é sobre o conceito de ONE WAY DATA FLOW, é como um componente funciona, como ilustrado na imagem abaixo.

Para compartilhar estado entre diversos componentes, cada um com seu ONE WAY DATA FLOW, precisamos da “idéia” do Padrão de projeto Singleton.

Em uma aplicação SPA, um singleton é por navegador/aba, oque significa que se você quiser compartilhar estado entre duas pessoas diferentes, cada uma em seu computador, este tipo de solução não vai funcionar. Neste caso você precisará manter estado no servidor, pra isto o Google Firebase pode te ajudar, e muito ;)

Por meio de um Singleton os componentes podem mudar o estado e compartilha-lo.

Vuex

A idéia do Vuex é a de ser um singleton. Permitindo gerenciar, armazenar e alterar um estado de modo que possa ser compartilhado. Inspirado no flux e no redux (React), mas adaptado e otimizado para o Vue. Por isto, os conceitos são os mesmos.

É difícil mensurar quando uma aplicação precisa do Vuex, mas de maneira geral, apenas grandes aplicações realmente obtêm proveito deste modelo arquitetural. Dan Abramov, criador do Redux disse: “Bibliotecas flux são como óculos, você vai saber quando precisar”.

Como funciona?

Store é o coração do Vuex, por isto, tenha certeza de entender oque é e como funciona. É onde guardamos todos os estados da aplicação ou funcionalidade; é reativa; não pode alterar os dados diretamente; precisa criar um “mutation” e realizar um “commit” desta “mutation”.

npm i — — vuex save

State

Como disse a pouco, a idéia do Vuex é ser um Singleton, logo, nós temos um único objeto controlando todo o estado compartilhado da nossa aplicação, e por isto é chamado de “unica fonte da verdade”.

Store

Quando você olhar para um store, você deve criar um modelo metal, e ao olhar o state deve imaginar ele como o data que usamos em componentes VueJS e o mutations como o methods.

Com este código acima, você poderia acessar o store como mostrado abaixo:

console.log(store.state.count);

Afim de mantermos o histórico, permitindo utilizar-lo como ferramenta de depuração (debug), ou retornar o valor anterior, para alterar o valor do estado invocamos o mutation através do método store.commit:

store.commit(‘increment’)
console.log(store.state.count)

Quando desejar utilizar uma propriedade da store (o state) no componete VueJS, utilize as computed properties, elas possuem um sistema de cache, que será limpo quando existirem alterações na store, isto provocará a mudança no DOM, renderizando a alteração na view (Mas é claro Dr. Óbvio). E para chamar o mutation, não há segredo, pode chamar-los normalmente nos methods.

Na prática, precisamos de acesso ao store em diversos componentes, para isto, o Vuex fornece um modo de injetar a store em todos os componentes, mas, a injeção de só irá funcionar se registrarmos o Vuex no Vue como um plugin e adicionar a store na raiz da arvore de componentes para que seja acessível em todos os componentes filhos, utilizando por exemplo:

this.$store.state.count

Getter

Para o Vuex, esta é a maneira que ele te oferece um meio de criar métodos, que retornam o estado do store levemente modificado, mas sem alterar o valor original.

Você poderia adicionar ao código acima, mais um getter, de maneira que te permita encadear getters, neste caso o segundo getter utilizaria o doneTodos assim:

Mutations

Fazendo o commit de uma mutation, é o único caminho para se alterar o estado no Vuex, similares a eventos, cada mutation possuí uma string que identifica o método declarado na store, que modificará o estado da aplicação.

Veja, no exemplo abaixo, a mutation increment, atente para o fato dela receber o state que é obrigatório.

Atenção: As mutations são síncronas e as actions são assincronias

Actions

Duas características são marcantes nas Actions:

  • É assincrona;
  • Faz commit de uma mutation para efetuar a alteração do estado

Observe no código abaixo, que a action incremente recebe um objeto context (obrigatório), e através dele que é realizado o commit

Você já deve ter entendido, que requisições a servidores devem ser feitas nas action (Mas é claro Dr. Óbvio :D )

É através do context que você terá aceso ao state(context.state), getters (context.getters)

Exemplo de um carrinho de compras utilizando Vuex:

E pra finalizar, quero te convidar a conhecer mais sobre o Vue no meu curso on-line, disponível na Udemy. Utilize o cupom de desconto 99DE75 e pague apenas R$75 reais, no curso completo, ainda recebendo atualizações, e de acesso vitalício :D

Faça o curso de Vue, que também tem aulas de Vuex, Bulma, Vue Material Design, e Vuetify.