Utilizar Vuex para la gestión de estados
Compartir un estado global entre varios componentes
1. Problemática
a. El flujo de datos unidireccional
Como recordatorio, Vue.js usa un flujo unidireccional para actualizar los datos del modelo desde la vista y aplica estos cambios durante el siguiente procesamiento:
El proceso funciona de la siguiente manera en una instancia de Vue.
-
Vista: el usuario interactúa con la vista, por ejemplo mediante el clic de un botón. El botón llama a una acción usando un método de la instancia de Vue.
-
Acción: esta acción cambia el estado de la aplicación, modificando los datos reactivos del modelo.
-
Estado: el estado de la aplicación ahora es diferente. Con su mecanismo de enlace de datos (data-binding), Vue.js actualiza la vista con una nueva representación.
Se podría decir que una aplicación de Vue.js se basa en datos.
Una aplicación Vue.js es un árbol de componentes. Cada componente tiene datos reactivos que definen su estado, lo que significa que, en última instancia, el estado de cada componente representa el estado de la aplicación.
Podemos encontrar diferentes problemas cuando queremos compartir un estado entre varios componentes.
-
Problema 1: compartir estos datos en modo lectura. Si varios componentes quieren mostrar los mismos datos reactivos, ¿cómo los comparte? La vista de un componente puede mostrar datos reactivos de su modelo, pero no puede acceder a los datos reactivos de otro componente.
-
Problema 2: compartir estos datos para modificarlos. Se pueden realizar varias acciones desde diferentes vistas para modificar los datos reactivos compartidos.
¿Cómo solucionar estos dos problemas?
b. Utilizar props y eventos para compartir y acceder al estado global
En el capítulo Utilizar los componentes, vimos que podemos usar props para pasar datos reactivos de un componente padre a uno hijo.
Para resolver el primer problema, la primera idea es colocar en la instancia raíz de Vue los datos reactivos que queremos compartir entre componentes. Por lo tanto, la instancia tendrá el estado global. Posteriormente, estos datos se pasan a través de las props a cada componente hijo.
Para mutar los datos reactivos de la instancia raíz de un componente hijo, es necesario emitir un evento que recuperará el padre.
Para resolver el segundo problema, es necesario emitir...
Instalar y utilizar store Vuex
1. Instalación
a. Con un CDN
Para instalar Vuex si no está usando un empaquetador de módulos, puede usar un CDN insertando esta línea en la página web:
<script src="https://unpkg.com/vuex@3.6.0/dist/vuex.js" />
b. Con npm o yarn
Si está utilizando un empaquetador de módulos, puede instalar Vuex con el administrador de dependencias npm o yarn.
En un terminal, vaya a la raíz de su proyecto y escriba la siguiente línea de comandos:
// con npm
npm install vuex --save
// con yarn
yarn add vuex
Después use el método Vue.use() para declarar el módulo globalmente en su aplicación:
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
Para crear la store utilizamos el método Vuex.Store(), que recibe como parámetro un objeto que contiene el estado, getters, setters, acciones y módulos.
Después pasamos la store en las opciones de instancia, al crear una instancia de la instancia raíz de Vue.
// archivo main.js
import Vue from 'vue';
import Vuex from 'vuex';
import App from './App.vue';
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
},
getters: {
},
mutations: {
},
actions: {
},
modules: {
},
});
new Vue({
store,
render: (h) => h(App),
}).$mount('#app');
En este momento, la store se inyectará en todos los componentes hijo de la instancia raíz de Vue y se podrá acceder a ella con la variable de instancia this.$store.
c. Con Vue CLI
Si ha instalado su proyecto con Vue CLI pero Vuex aún no está instalado, puede instalar Vuex con el siguiente comando:
vue add vuex
Se crea automáticamente un archivo store/index.js:
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
},
mutations: { ...
Utilizar los módulos para organizar su store
1. Separar el store en varios archivos
Para aplicaciones grandes, el archivo store/index.js puede crecer rápidamente. Si queremos ganar en legibilidad, sería interesante poder separar el estado de la store en varios archivos. Cada archivo contendría una parte de la store, con las mutaciones y acciones asociadas.
El primer enfoque que viene a la mente es utilizar módulos ES6:
// archivo store/partA.js
export default {
state: {
count: 0
},
mutations: {
CHANGE_COUNT(state, number) {
state.count = number;
}
}
};
// archivo store/partB.js
export default {
state: {
message: "mi mensaje"
},
mutations: {
CHANGE_MESSAGE(state, message) {
state.message = message;
}
}
};
Después fusionamos las diferentes partes para cada propiedad de la store usando la descomposición:
// archivo store/index.js
import Vue from "vue";
import Vuex from...