#code  #vue  #javascript 

Grey mac

Al desarrollar aplicaciones web, a medida que estas crecen y se vuelven más complejas, se hace necesario contar con un medio para administrar información de forma global a la aplicación de forma estándar. Entre las soluciones comúnmente usadas para enviar y recibir información entre páginas se encuentra el envío de datos a través del URL, las cookies y el LocalStorage. Todas éstas formas si bien son funcionales no proveen de un estándar para la manipulación de los datos y no son fuentes de datos reactivas que hagan armonía con la reactividad de Vue.js.

Evan You, creador de Vue.js, desarrolló una herramienta llamada Vuex especialmente diseñada para Vue que permite el manejo centralizado de datos en aplicación web desarrolladas con este framework. Si bien no es la única herramienta para el manejo de datos, es la que mejor se integra con el ecosistema de Vue.

Vuex es una librería de manejo de patrones de estado para aplicaciones Vue.js. Provee un almacenamiento centralizado para todos los componentes en la aplicación, con reglas que aseguran que los datos sólo puedan ser modificados de forma predecible.

Usar Vuex es especialmente recomendado para aplicaciones medianas y grandes donde se requiere información centralizada y reactiva accesible a través de distintos componentes.

Instalación

A través de un CDN, colocándolo después de vue

<script src="/path/to/vue.js"></script>
<script src="/path/to/vuex.js"></script>

Utilizando NPM

npm install vuex --save

Utilizando Yarn

yarn add vuex

Al usar un sistema de módulos (como webpack en el vue-cli), es necesario instalar Vuex a través de Vue.use()

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

Estructura básica de Vuex

const store = new Vuex.Store({
	state: {},
	mutations: {},
	actions: {},
	getters: {},
})

state

El state es el objeto que contiene todos los datos que podemos acceder desde los distintos componentes. Su contenido sólo debe ser modificado a través de las mutations de tal forma que la modificación del mismo sea transparente y auditable.

state: {
  contador: 0
}

mutations

La única forma de modificar el statede un almacenamiento Vuex es a través de una mutation. En estas funciones es que se realizan las modificaciones y las mismas reciben el statecomo primer parámetro.

mutations: {
  incrementar (state) {
    state.contador++
  }

Las mutaciones no se pueden llamar directamente, por lo que son ejecutadas con store.commit

store.commit('incrementar')

Las mutaciones también pueden recibir datos como segundo parámetro, esto puede ser un número, una cadena, un arreglo, etc…

mutations: {
  incrementar (state, cantidad) {
    state.contador += cantidad
  }
store.commit('incrementar', 10)

Un punto importante es saber que las mutaciones son síncronas, es decir cualquier modificación al statedebe realizar de una vez y no a través de transacciones asíncronas como consultas a bases de datos o APIs. Para modificaciones asíncronas al state se utilizan los actions.

actions

Los actions son similares a las mutaciones excepto por dos diferencias:

  • Se ejecutan con store.dispatch
  • En vez de modificar el state, los actions realizan mutaciones.
  • Los actions pueden contener código asíncrono.
  • Reciben como primer parámetro una variable context que nos da acceso al state y a las mutations, actions y getters.
  • Los actions pueden retornar una promesa una vez son resueltos.

Suponiendo que quisiéramos incrementar el contador después de una consulta a algun API podríamos hacerlo de la siguiente forma

actions: {
  incrementoAsincrono (context) {
    return new Promise((resolve, reject) => {
      fetch('algunApiX').then(() => {
        context.commit('incrementar')
        resolve()
      })
    })
  }
}

o utilizando async/await

actions: {
  async incrementoAsincrono (context) {
    await fetch('algunApiX')
    context.commit('incrementar')
  }
}

y utilizarlo de la siguiente forma

store.dispatch('incrementoAsincrono').then(() => console.log('¡Contador incrementado!'))

Conoce más sobre Promesas de Javascript y sobre Async/Await.

getters

Los getters son utilizados para traer información del state de forma procesada. Estos reciben el state como primer argumento.

Suponiendo que en el statetuviéramos un listado de tareas, podríamos crear un getter que retorne solamente las tareas completadas.

state: {
  tareas: [
  { id: 1, texto: 'lorem ipsum', realizada: true },
  { id: 2, texto: 'lorem ipsum', realizada: true },
  { id: 3, texto: 'lorem ipsum', realizada: false },
  { id: 4, texto: 'lorem ipsum', realizada: false },
  { id: 5, texto: 'lorem ipsum', realizada: true },
  ],
},
getters: {
  tareasRealizadas (state) {
    return state.tareas.filter(tarea => tarea.realizada)
  }
}

y usarlo de esta forma

store.getters.tareasRealizadas
/*
[
  { id: 1, texto: 'lorem ipsum', realizada: true },
  { id: 2, texto: 'lorem ipsum', realizada: true },
  { id: 5, texto: 'lorem ipsum', realizada: true },
]
*/

Los getters también pueden recibir datos retornando una función. Es decir que podríamos traer una tarea específica por id a través de un getter de la siguiente forma

getters: {
  tareasRealizadasPorId (state) => (id) => {
    return state.tareas.filter(tarea => tarea.id === id)
  }
}

Y usarlo así

store.getters.tareasRealizadasPorId(2) // [{ id: 2, texto: 'lorem ipsum', realizada: true }]

De esta forma podemos manejar información accesible en nuestros componentes la cual es manipulable a través de los mutations y los actions y la cual podemos consultar de forma procesadas a través de los getters. Dándole a nuestra aplicación un patrón de uso de datos estándar que nos permite escalar más rápidamente.

Compartir

Relacionados


Utilizar JSON Web Token con Laravel para crear APIs

Persistir la información con Vuex

Define valores por defecto en JavaScript

Parámetros por defecto en JavaScript