Aprenda Vuex en 5 minutos

Este tutorial le dará una comprensión básica de Vuex mediante la creación de una aplicación de creación de planes. Un usuario puede escribir actividades y luego votar cuánto le gustan / no le gustan.

Una vez que haya leído este tutorial, puede consultar nuestro curso gratuito de Vuex en Scrimba, si está interesado en obtener más información.

¿Qué es Vuex? De la documentación oficial de Vue

Vuex is a state management pattern + library for Vue.js applications. It serves as a centralized store for all the components in an application, with rules ensuring that the state can only be mutated in a predictable fashion. 

Este curso asume que está algo familiarizado con Vue y brevemente tocaremos características como propscomponentes y enlaces, pero no las revisaremos con gran detalle. Si desea tener una introducción rápida a Vue, no dude en consultar este curso en Scrimba.

La puesta en marcha

En Scrimba, las configuraciones complicadas son algo que simplemente no hacemos.

Para este tutorial, hemos creado un archivo HTML simple donde se puede escribir todo. Siéntase libre de escribir su propio CSS o simplemente copiarlo de este campo de juegos

Las bibliotecas Vue y Vuex se importan a través de CDN mediante etiquetas:

         Activity Voter                      /*         ADD CSS HERE       */ /*       ADD VUE CODE HERE     */     

Alternativamente, también puede experimentar con el código en este área de juegos de Vue Scrimba. Recuerde volver a vincular el área de juegos a su propia cuenta.

Plan de aplicación

Vamos a crear una aplicación de votación, que funciona especialmente bien cuando estás en un grupo de amigos sin saber qué hacer y tienes que considerar todas las opciones.

La funcionalidad consistirá en que un usuario pueda escribir una actividad y luego cada actividad tendrá un botón de voto hacia arriba y hacia abajo para contar los totales.

Empezando

Primero, simulemos rápidamente nuestra aplicación en HTML. Usaremos este diseño para luego extraerlo en un componente separado y agregaremos funcionalidad para que el diseño cobre vida.

Activity voter

          Add Activity    
       
  •       Go Snowboarding ?         ?         5         ?          
  •  

Agregue la tienda Vuex con algunos datos básicos

Vuex comienza con la tienda. La tienda es donde guardamos (almacenamos) nuestro estado.

   Vue.use(Vuex);   const store = new Vuex.Store({   });   new Vue({     el: "#app",     store   });  

Agreguemos también algunos datos codificados a la tienda, que incluirán una actividad y una matriz con un emoji para mostrar nuestros sentimientos hacia la actividad.

   Vue.use(Vuex);   const store = new Vuex.Store({     state: {       activities: [{ name: "go snowboarding", rating: 5 }],       emojis: ["?"]     }   });   new Vue({     el: "#app",     store   });  

Para permitir que nuestro estado cambie de forma reactiva, podemos usar Vuex mapStatepara manejar las propiedades del estado calculado por nosotros.

  new Vue({     el: "#app",     store,     computed: Vuex.mapState(["activities", "emojis"])   }); 

Agregar componente

Ahora tenemos actividades dentro de nuestro estado. Representemos un componente separado para cada una de esas actividades. Cada uno necesitará activityy emojisaccesorios.

Vue.component("activity-item", {   props: ["activity", "emojis"],   template: `     
  •       {{ activity.name }}         {{ emojis[0] }}         ?         {{activity.rating}}         ?          
  •     ` });

    Dentro app, ahora podemos usar nuestro componente recién creado con todos los enlaces apropiados activityy emojis. Como recordatorio rápido, si queremos recorrer una matriz y mostrar un componente para cada elemento en una matriz, en Vue, podemos usar el v-forenlace.

    Activity voter

              Add Activity    
         

    Agregar mutaciones para almacenar

    Si queremos actualizar la tienda en Vuex, podemos usar mutaciones. Por el momento solo console.logsabremos que ocurrió una mutación y la implementaremos después.

    const store = new Vuex.Store({   state: {     activities: [       { name: "go snowboarding", rating: 5 },     ],     emojis: ["?"]   },   mutations: {     increment(state, activityName) {       console.log('increment');     },     decrement(state, activityName) {       console.log('decrement');     },   } }); 

    ¿Cómo desencadenamos una mutación? Invocamos una commitfunción $storecon el nombre de las mutaciones que queremos que se ejecuten. Cualquier argumento después del nombre de una mutación se trata como argumentos para una mutación cometida.

    new Vue({   el: "#app",   store,   data() {     return {       activityName: ""     };   },   computed: Vuex.mapState(["activities", "emojis"]),   methods: {     increment(activityName) {       this.$store.commit("increment", activityName);     },     decrement(activityName) {       this.$store.commit("decrement", activityName);     }   } }); 

    Agregar funcionalidad al componente

    Each activity-item has voting buttons that need to increment and decrement on click of a button. We can pass these functions as props. Let's now bind our methods to props.

    Let's also not forget to provide activity.name as an argument to both.

    Vue.component("activity-item", {   props: ["activity", "emojis", "increment", "decrement"],   template: `     
  •       {{ activity.name }}           {{ emojis[0] }}           ?           {{activity.rating}}           ?          
  •     ` });

    And there we go! The flow is working. We can see the console.log statement in the console.

    Implement counter

    Let's implement the counter. First, we need to find an activity by its name, and then update its rating.

      mutations: {     increment(state, activityName) {       state.activities         .filter(activity => activity.name === `${activityName}`)         .map(activity => activity.rating++);     },     decrement(state, activityName) {       state.activities         .filter(activity => activity.name === `${activityName}`)         .map(activity => activity.rating--);     }   } 

    Perfect, we can now vote on activities.

    Use form input to add activity

    But of course, we need to be able to add activities too.

    Let's create a mutation to the store, that would add an activity to the list of existing activities, with a name that we will later get from the input and a default rating of 0.

     mutations: {     ...     addActivity(state, name) {       state.activities.push({ name, rating: 0 });     }   } 

    Inside methods, we can commit a new activity to the store.

    methods: {     ...     addActivity(activityName) {       this.$store.commit("addActivity", activityName);     }   } 

    Implement form submission

    Let's wire up the submit function to our HTML form.

          Add Activity  

    We can now add our submit function to methods. Inside, we're going to use our existing addActivity method and in the end, reset activityName in the input field to an empty string.

    methods: {     ...     onSubmit(e) {       e.preventDefault();       this.addActivity(this.activityName);       this.activityName = "";     }   } 

    We call e.preventDefault() to avoid the form from reloading on each addition of a new activity.

    All the counters now work and the field gets updated. It does look a bit strange, that we have only one emotion for all the activities, no matter what their rating is.

    Let's rewrite emojis into an object with some description of what moods they are meant to reflect and clean up existing state, so we start from no activities.

    state: {     activities: [],     emojis: { yay: "?", nice: "?", meh: "?", argh: "?", hateIt: "?"} }, ... 

    And as a finishing touch, we can display different emojis depending on the rating an activity has.

    Vue.component("activity-item", {   props: ["activity", "emojis", "increment", "decrement"],   template: `     
  •       {{ activity.name }}             ` });
  • We start with a blank app, which is what we wanted.

    And now if we add back the two activities we used to have in the app, vote on the ratings we have emojis that reflect how we feel about the activities!

    You can check out the full code here.