Gestión de Estado en Vue 3 con Vuex: Guía Completa

El manejo del estado global en aplicaciones Vue 3 se simplifica enormemente con Vuex, especialmente cuando múltiples componentes necesitan compartir y modificar datos. A continuación, se detalla cómo integrar y utilizar Vuex en tu proyecto Vue 3, abarcando sus componentes clave: state, mutations, actions y getters.

  1. Instalación de Vuex Asegúrate de tener un proyecto Vue 3 configurado. Luego, instala la versión compatible de Vuex:
npm install vuex@next --save

O con Yarn:

yarn add vuex@next --save

  1. Configuración Inicial del Store En Vue 3, la creación del store se adapta a la Composition API. Crea un archivo, por ejemplo store/index.js, y define tu store:
import { createStore } from 'vuex';

const store = createStore({
  state() {
    return {
      counterValue: 0,
    };
  },
  mutations: {
    aumentar(state) {
      state.counterValue++;
    },
    establecerValor(state, payload) {
      state.counterValue = payload;
    }
  },
  actions: {
    incrementarAsync({ commit }) {
      // Simula una operación asíncrona, como una llamada API
      setTimeout(() => {
        commit('aumentar');
      }, 1000);
    },
    actualizarContador({ commit }, newValue) {
      commit('establecerValor', newValue);
    }
  },
  getters: {
    dobleContador(state) {
      return state.counterValue * 2;
    },
    contadorFormateado(state) {
      return `Valor actual: ${state.counterValue}`;
    }
  },
});

export default store;

  1. Integración del Store en la Alpicación Vue Modifica tu archivo de entrada principal (generalmente main.js o main.ts) para usar el store configurado:
import { createApp } from 'vue';
import App from './App.vue';
import store from './store'; // Importa tu store

const app = createApp(App);
app.use(store); // Registra Vuex en la aplicación
app.mount('#app');

  1. Uso de Vuex en Componentes Vue

Acceso al State Utiliza la función useStore de Vuex para acceder al estado desde la Composition API:

<template>
  <div>Valor: {{ valorActual }}</div>
</template>

<script setup>
import { useStore } from 'vuex';
import { computed } from 'vue';

const store = useStore();
const valorActual = computed(() => store.state.counterValue);
</script>

Mutations para Cambios Síncronos Llama a commit para ejecutar mutations que modifican el estado de forma síncrona:

<template>
  <button @click="incrementar">Aumentar</button>
</template>

<script setup>
import { useStore } from 'vuex';

const store = useStore();

function incrementar() {
  store.commit('aumentar');
}
</script>

Actions para Operaciones Asíncronas Usa dispatch para ejecutar actions, ideales para lógica asíncrona como peticiones HTTP:

<template>
  <button @click="iniciarIncrementoAsync">Aumentar Asíncronamente</button>
</template>

<script setup>
import { useStore } from 'vuex';

const store = useStore();

function iniciarIncrementoAsync() {
  store.dispatch('incrementarAsync');
}
</script>

Getters para Calcular Datos Derivados Accede a los getters para obtener valores calculados a partir del estado:

<template>
  <div>Doble del valor: {{ valorDoble }}</div>
  <div>{{ valorFormateado }}</div>
</template>

<script setup>
import { useStore } from 'vuex';
import { computed } from 'vue';

const store = useStore();

const valorDoble = computed(() => store.getters.dobleContador);
const valorFormateado = computed(() => store.getters.contadorFormateado);
</script>

  1. Ayudantes de Vuex (Map Helpers) Vuex proporciona funicones auxiliares para simplificar el mapeo de estado, getters, mutations y actions en componentes, especialmente útil con la Options API, aunque adaptable a Composition API:

useStoreProporciona acceso al store:

import { useStore } from 'vuex';

export default {
  setup() {
    const miStore = useStore();
    return { miStore };
  }
}

Mapeo con Composition API (Usando computed y methods) En Vue 3, es más común usar computed para getters y methods para commits/dispatches directamente o con helpers si se prefiere una sintaxis similar a Options API.

Ejemplo con mapState (adaptado):

import { useStore } from 'vuex';
import { computed } from 'vue';

export default {
  setup() {
    const store = useStore();
    
    // Mapeo de estado
    const contador = computed({
      get: () => store.state.counterValue,
      set: (newValue) => store.commit('establecerValor', newValue)
    });

    return { contador };
  }
}

Ejemplo con mapGetters (adaptado):

import { useStore } from 'vuex';
import { computed } from 'vue';

export default {
  setup() {
    const store = useStore();
    
    // Mapeo de getters
    const dobleValor = computed(() => store.getters.dobleContador);

    return { dobleValor };
  }
}

Ejemplo con mapMutations (adaptado):

import { useStore } from 'vuex';

export default {
  setup() {
    const store = useStore();
    
    // Mapeo de mutations
    const incrementar = () => store.commit('aumentar');

    return { incrementar };
  }
}

Ejemplo con mapActions (adaptado):

import { useStore } from 'vuex';

export default {
  setup() {
    const store = useStore();
    
    // Mapeo de actions
    const ejecutarAccionAsync = () => store.dispatch('incrementarAsync');

    return { ejecutarAccionAsync };
  }
}

  1. Módulos de Vuex Para aplicaciones más grandes, Vuex soporta módulos para organizar el store:
// store/modules/usuario.js
const state = {
  nombreUsuario: 'Invitado',
};

const getters = {
  saludoPersonalizado(state) {
    return `Hola, ${state.nombreUsuario}!`;
  },
};

const mutations = {
  establecerNombre(state, payload) {
    state.nombreUsuario = payload;
  },
};

const actions = {
  actualizarNombreUsuario({ commit }, nuevoNombre) {
    commit('establecerNombre', nuevoNombre);
  },
};

export default {
  namespaced: true, // Habilita el namespace para este módulo
  state,
  getters,
  mutations,
  actions,
};

Y agrégalo a tu store principal:

// store/index.js
import { createStore } from 'vuex';
import usuarioModule from './modules/usuario';

const store = createStore({
  modules: {
    usuario: usuarioModule, // Registra el módulo 'usuario'
  },
  // ... otros estados, mutations, actions, getters globales si los hay
});

export default store;

En un componente, accederías a un módulo con namespace así:

<template>
  <div>{{ saludo }}</div>
  <button @click="cambiarNombre('Alice')">Cambiar Nombre</button>
</template>

<script setup>
import { useStore } from 'vuex';
import { computed } from 'vue';

const store = useStore();

// Acceso a getter con namespace
const saludo = computed(() => store.getters['usuario/saludoPersonalizado']);

// Ejecución de mutation con namespace
function cambiarNombre(nombre) {
  store.commit('usuario/establecerNombre', nombre);
}

// Ejecución de action con namespace
// store.dispatch('usuario/actualizarNombreUsuario', 'Bob');
</script>

Etiquetas: vuex Vue 3 gestión de estado Composition API

Publicado el 7-26 01:12