Dominando Vuex - De cero a h茅roe

Hola Habr! Les presento la traducci贸n del art铆culo "Dominando Vuex - Zero to Hero" por Sanath Kumar.


La documentaci贸n oficial de Vuex lo define como un patr贸n de gesti贸n de estado + biblioteca para aplicaciones Vue.js. 驴Pero qu茅 significa eso? 驴Qu茅 es un patr贸n de gesti贸n estatal?


Imagine que est谩 trabajando en una gran aplicaci贸n web con cientos de rutas y componentes. 驴No ser铆a m谩s f谩cil si pudi茅ramos almacenar todos los datos que necesitar铆amos en una aplicaci贸n en un almacenamiento centralizado?



Cada componente o ruta dentro de nuestra aplicaci贸n solicitar谩 datos del estado de Vuex y transferir谩 los datos modificados nuevamente al estado.


En esencia, el estado de Vuex puede verse como la 煤nica fuente de verdad para toda la aplicaci贸n.


Los datos se almacenan dentro del estado como un objeto JSON. Por ejemplo:


state: { name: "John Doe", age: "28" } 

Pero, 驴c贸mo pueden nuestros componentes y rutas acceder a los datos almacenados en nuestro estado? Para hacer esto, necesitamos definir captadores dentro de nuestro repositorio Vuex que devolver谩n los datos del repositorio a nuestros componentes. Veamos c贸mo se ve un getter simple, que obtiene el nombre de nuestro repositorio:


 getters: { NAME: state => { return state.name; }, } 

Observe que el nombre del captador est谩 en may煤sculas. Esto es solo una recomendaci贸n de estilo de c贸digo. No es necesario seguirlo si no te gusta.


Ahora que hemos definido un captador para el nombre, es incre铆blemente f谩cil obtener el valor del nombre dentro de nuestro componente. El siguiente c贸digo le permite hacer esto.


 let name = this.$store.getters.NAME; 

Descubrimos c贸mo obtener datos del almacenamiento. Ahora veamos c贸mo podemos establecer los datos en el repositorio. Definiremos setters, 驴verdad? Adem谩s, los setters de Vuex se nombran un poco diferente. Definimos una mutaci贸n para establecer datos en nuestro estado Vuex.


 mutations: { SET_NAME: (state, payload) => { state.name = payload; }, } 

驴Qu茅 m谩s es la carga 煤til? La carga 煤til son los datos transmitidos a nuestra mutaci贸n desde el componente que hace la mutaci贸n. 驴C贸mo podemos hacer esto? Muy simple:


 this.$store.commit('SET_NAME', your_name); 

Este c贸digo cambiar谩 el estado de la aplicaci贸n y establecer谩 cualquier valor asignado a your_name para la propiedad de nombre dentro de nuestro repositorio.


MUTACIONES SINCRONICAS


Imagine que tenemos una lista de nombres almacenados en una base de datos en un servidor remoto. El servidor nos proporciona un punto final que devuelve una serie de nombres que se pueden usar en nuestro Vue.js. Por supuesto, podemos usar Axios para consultar el punto final y obtener los datos.


 let {data} = await Axios.get('https://myapiendpoint.com/api/names'); 

Despu茅s de eso, podemos pasar la matriz devuelta a nuestro estado Vuex de la tienda usando una mutaci贸n. F谩cil, verdad? Pero en realidad no. Las mutaciones son s铆ncronas, y no podemos ejecutar operaciones as铆ncronas, como llamadas de API, dentro de una mutaci贸n.


驴Qu茅 debemos hacer entonces? Crea acciones .


Las acciones son como mutaciones, pero en lugar de cambiar directamente el estado, hacen una mutaci贸n. 驴Suena confuso? Veamos el anuncio de la acci贸n.


 actions: { SET_NAME: (context, payload) { context.commit('SET_NAME', payload); }, } 

Definimos una acci贸n llamada SET_NAME que toma el contexto y la carga 煤til como par谩metros. La acci贸n confirma la mutaci贸n SET_NAME, creada anteriormente, con los datos que se le pasan, es decir, su_nombre .


Ahora, en lugar de invocar la mutaci贸n directamente, nuestros componentes activan la acci贸n SET_NAME con un nuevo nombre como datos de la siguiente manera:


 this.$store.dispatch('SET_NAME', your_name); 

Luego, la acci贸n inicia la mutaci贸n con los datos que se le pasan, es decir, su_nombre .



Pero por que?


Quiz谩s se pregunte por qu茅 se requiere una declaraci贸n de acci贸n si simplemente podemos iniciar mutaciones con un nuevo valor directamente desde nuestros componentes. Como se mencion贸 anteriormente, las mutaciones son sincr贸nicas, pero no acciones.


En el ejemplo anterior, el caso se considera cuando necesita actualizar el valor del nombre, pero no solo en su estado, sino tambi茅n en la base de datos que se ejecuta en el servidor remoto. Estoy seguro de que as铆 es como pretende utilizar Vuex en un proyecto real en el 99% de los casos. Eche un vistazo al siguiente fragmento de c贸digo:


 mutations: { SET_NAME: (state, name) => { state.name = name; }, }, actions: { SET_NAME: async (context, name) => { let {data} = await Axios.post('http://myapiendpoint.com/api/name', {name: name}); if (data.status == 200) { context.commit('SET_NAME', name); } }, } 

El c贸digo en s铆 se explica por s铆 mismo. Usamos Axios para enviar el nombre al punto final. Si la solicitud POST se realiz贸 correctamente y el valor del nombre del campo se modific贸 correctamente en el servidor, iniciamos la mutaci贸n SET_ NAME para actualizar el valor del nombre dentro de nuestro estado.


TOMA PR脕CTICA NUNCA INICIES MUTACIONES DIRECTAMENTE. PARA ESTE SIEMPRE USE ACCIONES.



Configurar el almacenamiento de Vuex en Vue.JS


Profundicemos m谩s y descubramos c贸mo podemos implementar Vuex en una aplicaci贸n real.


Paso 1. Instala Vuex


 npm install --save vuex 

Paso 2. Crear un repositorio de Vuex


  1. Cree el directorio de la tienda en la ra铆z de nuestra aplicaci贸n.
  2. Cree el archivo index.js en este directorio y use el siguiente c贸digo para crear un nuevo repositorio.

 import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); export const store = new Vuex.Store({ state: {}, getters: {}, mutations: {}, actions: {}, }); 

Paso 3. Agregar almacenamiento Vuex a la aplicaci贸n Vue.JS


1. Importe el repositorio al archivo main.js:


 import {store} from './store'; 

2. Agregue almacenamiento a la instancia de Vue, como se muestra a continuaci贸n:


 new Vue({ el: '#app', store, router, render: h => h(App), }); 

Ahora podemos agregar variables de estado, captadores, mutaciones y acciones a nuestro repositorio Vuex.



Ejemplo


Eche un vistazo al repositorio de Vuex de una aplicaci贸n de lista de tareas simple. "隆No solo otra lista de tareas pendientes!". 驴Eh? No te preocupes Al final de este art铆culo, aprender谩 c贸mo usar todo el poder y el poder de Vuex.


 import Vue from 'vue'; import Vuex from 'vuex'; import Axios from 'axios'; Vue.use(Vuex); export const store = new Vuex.Store({ state: { todos: null, }, getters: { TODOS: state => { return state.todos; }, }, mutations: { SET_TODO: (state, payload) => { state.todos = payload; }, ADD_TODO: (state, payload) => { state.todos.push(payload); }, }, actions: { GET_TODO: async (context, payload) => { let {data} = await Axios.get('http://yourwebsite.com/api/todo'); context.commit('SET_TODO', data); }, SAVE_TODO: async (context, payload) => { let {data} = await Axios.post('http://yourwebsite.com/api/todo'); context.commit('ADD_TODO', payload); }, }, }); 


Agregar un nuevo elemento a la lista de tareas


Dentro de su componente, inicie la acci贸n SAVE_TODO pas谩ndole un nuevo elemento de tarea pendiente, como se muestra en el fragmento de c贸digo a continuaci贸n.


 let item = 'Get groceries'; this.$store.dispatch('SAVE_TODO', item); 

La acci贸n SAVE_TODO realiza una solicitud POST al punto final y luego inicia la mutaci贸n ADD_TODO , que agrega un elemento de tarea pendiente a la variable de estado todos .



Obtenci贸n de tareas pendientes


Dentro del bloque montado () de su componente, inicie la segunda acci贸n GET_TODO , que recibe todos los elementos de tareas desde el punto final y los almacena en la variable de estado todos , iniciando la mutaci贸n SET_TODO:


 mounted() { this.$store.dispatch('GET_TODO'); } 


Acceda a tareas pendientes dentro de un componente


Para acceder al elemento todos dentro de un componente, cree una propiedad calculada:


 computed: { todoList() { return this.$store.getters.TODOS; }, } 

Dentro del componente, puede acceder a la propiedad calculada:


 <div class="todo-item" v-for="item in todoList"></div> 


Usando el m茅todo mapGetters


Hay una manera a煤n m谩s f谩cil de acceder a las tareas pendientes dentro de un componente utilizando el m茅todo mapGetters proporcionado por Vuex.


 import {mapGetters} from 'vuex'; computed : { ...mapGetters(['TODOS']), //    } 

Es posible que ya haya adivinado que el c贸digo dentro de la plantilla debe cambiarse, como se muestra en el fragmento a continuaci贸n.


 <div class="todo-item" v-for="item in TODOS"></div> 

Observe c贸mo usamos el operador de distribuci贸n ES6 [...] dentro de nuestras propiedades calculadas.


ALMACENAMIENTO DE VUEX NO ES SOLO LA FUENTE DEL ESTADO ACTUAL DE SU APLICACI脫N. TAMBI脡N ES EL 脷NICO PUNTO QUE DEBE CAMBIAR ESTE ESTADO.


Esto requiere una peque帽a explicaci贸n. Ya hemos aprendido c贸mo crear acciones para recibir e instalar elementos de tareas en nuestro repositorio. 驴Qu茅 sucede si necesitamos actualizar un elemento y marcarlo? 驴D贸nde ejecutamos el c贸digo para esto?


En Internet puede encontrar diferentes opiniones sobre este asunto. La documentaci贸n tambi茅n carece de una gu铆a clara al respecto.


Recomendar铆a almacenar todas las llamadas API dentro de las acciones en su repositorio Vuex. Por lo tanto, cada cambio de estado ocurre solo dentro del repositorio, lo que facilita la depuraci贸n y simplifica la comprensi贸n del c贸digo, y tambi茅n facilita la edici贸n del c贸digo.



Organizaci贸n del c贸digo


Guardar todas las variables de estado, captadores, acciones y mutaciones en un archivo r谩pidamente lo har谩 engorroso tan pronto como comience a trabajar con aplicaciones grandes. Veamos c贸mo puede organizar el almacenamiento en varios archivos como m贸dulos.


Cree un nuevo directorio dentro de su repositorio y as铆gnele el nombre m贸dulos . Agregue el archivo todos.js al directorio creado que contiene el siguiente c贸digo:


 const state = {}; const getters = {}; const mutations = {}; const actions = {}; export default { state, getters, mutations, actions, }; 

Ahora podemos mover las variables de estado, captadores, mutaciones y acciones del archivo index.js al archivo todos.js . Recuerde importar Axios . Todo lo que necesitamos hacer es informarle a Vuex que creamos el m贸dulo de almacenamiento y d贸nde encontrarlo. El archivo index.js actualizado deber铆a verse as铆:


 import Vue from 'vue'; import Vuex from 'vuex'; import Axios from 'axios'; import todos from './modules/todos'; Vue.use(Vuex); export const store = new Vuex.Store({ state: {}, getters: {}, mutations: {}, actions: {}, modules: { todos, }, }); 

El archivo todos.js se ver谩 as铆:


 import Axios from 'axios'; state = { todos: null, }; getters = { TODOS: state => { return state.todos; }, }; mutations = { SET_TODO: (state, payload) => { state.todos = payload; }, ADD_TODO: (state, payload) => { state.todos.push(payload); }, }; actions = { GET_TODO: async (context, payload) => { let {data} = await Axios.get('http://yourwebsite.com/api/todo'); context.commit('SET_TODO', data); }, SAVE_TODO: async (context, payload) => { let {data} = await Axios.post('http://yourwebsite.com/api/todo'); context.commit('ADD_TODO', payload); }, }; export default { state, getters, mutations, actions, }; 


Resumen


  1. El estado de la aplicaci贸n se almacena como un objeto JSON grande.
  2. Los captadores se utilizan para acceder a los valores almacenados en la tienda.
  3. Las mutaciones actualizan su condici贸n. Debe recordarse que las mutaciones son sincr贸nicas.
  4. Todas las operaciones asincr贸nicas deben realizarse dentro de las acciones . Las acciones cambian de estado, iniciando mutaciones.
  5. Establezca una regla para iniciar mutaciones exclusivamente a trav茅s de la acci贸n .
  6. Los m贸dulos se pueden usar para organizar su almacenamiento en varios archivos peque帽os.

Vuex hace que trabajar con Vue sea mucho m谩s f谩cil y divertido. Si es un principiante, puede haber situaciones en las que le resulte dif铆cil decidir si usar Vuex en ciertas 谩reas de su aplicaci贸n. Sigue tu instinto. Alcanzar谩s alta velocidad bastante r谩pido.

Source: https://habr.com/ru/post/es421551/


All Articles