Дізнайтеся Vuex за 5 хвилин

Цей підручник дасть вам базове розуміння Vuex, побудувавши додаток для планування. Користувач може вводити дії, а потім голосувати, наскільки вони їм подобаються / не подобаються.

Прочитавши цей підручник, ви можете ознайомитись з нашим безкоштовним курсом Vuex на Scrimba, якщо вам цікаво дізнатись більше.

Що таке Vuex? З офіційної документації 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. 

Цей курс передбачає, що ви дещо знайомі з Vue, і ми коротко торкнемося таких функцій, як propsкомпоненти та прив'язки, але не будемо їх детально розглядати. Якщо ви хочете отримати короткий праймер про Vue, сміливо переглядайте цей курс на Scrimba.

Налаштування

У Scrimba складні налаштування - це те, чого ми просто не робимо.

Для цього підручника ми створили простий HTML-файл, де можна писати все. Не соромтеся писати власний CSS або просто скопіювати його з цього майданчика

Бібліотеки Vue та Vuex імпортуються через CDN за допомогою тегів:

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

Крім того, ви також можете поекспериментувати з кодом на цьому ігровому майданчику Vue Scrimba. Не забудьте повторно зв’язати ігровий майданчик зі своїм обліковим записом.

План програми

Ми збираємося створити додаток для голосування, яке особливо добре працює, коли ви знаходитесь у групі друзів, які не знаєте, що робити, і вам доводиться розглядати всі варіанти.

Функціонал складатиметься з того, що користувач зможе ввести якусь діяльність, а потім кожна діяльність матиме кнопку голосування вгору і вниз для підрахунку підсумків.

Починаємо

По-перше, давайте швидко знущатись над нашим додатком у форматі HTML. Ми використаємо цей макет, щоб потім виділити його в окремий компонент, і ми додамо функціонал для того, щоб макет ожив.

Activity voter

          Add Activity    
       
  •       Go Snowboarding ?         ?         5         ?          
  •  

Додайте магазин Vuex з деякими основними даними

Vuex починається з магазину. Магазин - це місце, де ми зберігаємо (зберігаємо) свій стан.

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

Давайте також додамо в магазин деякі жорстко закодовані дані, які включатимуть одну діяльність та масив з одним смайликом, щоб відобразити наші почуття до цієї діяльності.

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

Щоб наш стан міг реактивно змінюватися, ми можемо використовувати Vuex mapStateдля обробки обчислених властивостей стану для нас.

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

Додати компонент

Зараз ми маємо діяльність всередині нашої держави. Давайте зробимо окремий компонент для кожного з цих видів діяльності. Кожному знадобляться activityі emojisреквізит.

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

    Усередині appми тепер можемо використовувати наш нещодавно створений компонент з усіма відповідними прив’язками activityта смайликами. Для швидкого нагадування, якщо ми хочемо прокрутити масив і відобразити компонент для кожного елемента в масиві, у Vue ми можемо використовувати v-forприв’язку.

    Activity voter

              Add Activity    
         

    Додайте мутації для зберігання

    Якщо ми хочемо оновити магазин у Vuex, ми можемо використовувати мутації. На даний момент ми просто зрозуміємо, console.logщо сталася мутація, і ми реалізуємо її згодом.

    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');     },   } }); 

    Як ми запускаємо мутацію? Ми викликаємо commitфункцію on $storeз назвою мутацій, які ми хочемо виконати. Будь-які аргументи після назви мутації трактуються як аргументи до здійсненої мутації.

    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);     }   } }); 

    Додайте функціональність компоненту

    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.