Vuex es una librería que ofrece Vue para gestionar el estado de la aplicación, centralizar información y funciones, haciéndolas accesibles desde cualquier componente. Se organiza de la siguiente manera:

No todas las aplicaciones necesitarán Vuex, tendrá sentido si se reutiliza el código o si hay componentes distantes que necesiten comunicarse. No tiene sentido, por ejemplo, que hagas un getter si solo lo vas a utilizar una vez y no se comunica con otro componente, para eso mejor una propiedad computed en el mismo componente que lo necesita.

Aquí podemos ver el ciclo de cómo se ejecuta:

En nuestro proyecto, definiremos Vuex en src/store/index.js:

import Vue from 'vue'
import Vuex from 'vuex'
 
import moduloTexto from './modules/moduloTexto'
import moduloCuenta from './modules/moduloCuenta'
import createPersistedState from 'vuex-persistedstate'
 
Vue.use(Vuex)
 
export default new Vuex.Store({
  state: {
  },
  mutations: {
  },
  actions: {
  },
  modules: {
    // Dividimos el estado en diferentes módulos que hagan referencia a diferentes ámbitos
    // Podríamos tener un módulo dedicado, por ejemplo, al login
    moduloTexto, moduloCuenta
  },
  // Para hacer que el estado persista tras refrescar la página
  plugins: [createPersistedState()]
})

En este ejemplo, sólo se están importando dos módulos. Podemos añadir la funcionalidad directamente en este archivo, pero si tenemos estados de diferentes ámbitos, es mejor tener varios módulos para favorecer la legibilidad del código. Los módulos se definirán en archivos .js que se encontrarán en src/store/modules/. Por ejemplo, moduloCuenta.js:

export default {
  // namespaced para mapear especificando el módulo   ...mapState('nombreModulo', ['estado', 'otroestado'])
  // también para los dispatch -> dispatch("modulo/nombreAction")
  namespaced: true,
  // ESTADO
  state: {
    cuenta: 0,
  },
  // MUTACIONES: sólo estas pueden modificar el estado
  mutations: {
    SUMAR(state, valor) {
      state.cuenta += valor;
    },
    RESETEAR(state) {
      state.cuenta = 0;
    },
  },
  // ACCIONES: se encargan de la lógica de negocio y llaman a las mutaciones
  actions: {
    sumarX({ commit }, valor) {
      commit("SUMAR", valor);
    },
    resetear({ commit }) {
      commit("RESETEAR");
    },
  },
  // GETTERS: para propiedades calculadas
  getters: {
    isMillonario: (state) => state.cuenta > 999999,
  },
};

Cuando tenemos diferentes módulos en nuestro store, estableceremos namepsace=true para que al utilizar su funcionalidad desde los componentes haya que indicar a qué módulo corresponden, haciendo también que el código sea más fácil de comprender.

Desde los componentes podemos acceder a la funcionalidad del store de las siguientes formas.

State y Getters

Para el estado y los getters disponemos respectivamente de mapState y mapGetters:

import { mapGetters } from "vuex";
import { mapState } from "vuex";
 
export default {
    computed: {
        ...mapState("modulo", ["variableState", "otroState"]),
        ...mapGetters("modulo", ["isTal", "isCual"])
    }    
}

De esta forma tendríamos disponibles estas opciones para llamarlas de la misma forma que al resto de variables o computed variables del componente, con this. en el código JavaScript, y con el nombre directamente en el template.

Si las variables del estado o getters que mapeamos no están en un módulo, sino directamente en el index.js de nuestro store, se indicaría directamente el array con sus nombres:

import { mapGetters } from "vuex";
import { mapState } from "vuex";
 
export default {
    computed: {
        ...mapState(["variableState", "otroState"]),
        ...mapGetters(["isTal", "isCual"])
    }    
}

Actions

Para ejecutar acciones desde nuestros componentes, no tendremos que importar nada, simplemente usar dispatch de esta manera:

this.$store.dispatch("modulo/action", parametro);

Si la acción no corresponde a ningún módulo, sólo tenemos que llamarla con el nombre de la propia acción. Las acciones son funciones que pueden tener parámetros, y como vemos éstos se le pasan después del nombre de la acción, separados por comas.