Zamora's Blog

Getting Started with Vuex

August 15, 2021

Set Up

Vuex can be installed in few ways including NPM. As for Vue.js, all examples below use version 2.

Create a Store

The following creates a Vuex store.

import Vue from "vue"
import Vuex from "vuex"

Vue.use(Vuex)

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

A store can also be created in a separate file and exported like below:

export default new Vuex.Store({
  state: {},
  mutations: {},
  actions: {},
  modules: {},
})

Make the Store Accessible

The store needs to be added to the Vue instance in order to retrieve the state in Vue components.

new Vue({
  el: "#app",
  store,
})

If the store is being exported from a separate file it will need to be imported. Here is an example from a Vue app generated by the Vue CLI.

import Vue from "vue"
import App from "./App.vue"
import store from "./PATH_TO_STORE_FILE"

new Vue({
  store,
  render: h => h(App),
}).$mount("#app")

Get State from the Store

To demonstrate how to retrieve state from the store I’ve added test data to the state object.

const store = new Vuex.Store({
  state: {
    username: "Random Person",
    age: 100,
    favoriteFoods: ["🌮", "🍤", "🍦"],
  },
  mutations: {},
  actions: {},
  modules: {},
})

Now that the store is initialized, the state can be called in a Vue component with this.$store.state.

<template>
  <div id="app">
    {{this.$store.state}}
  </div>
</template>

Update State

The state cannot be updated by directly mutating the state object.

// Don't do this!
const newObj = {}
this.$store.state = newObj

Methods set in the mutations field of the Vuex store are used to update state.

const store = new Vuex.Store({
  state: {
    username: "Random Person",
    age: 100,
    favoriteFoods: ["🌮", "🍤", "🍦"],
  },
  mutations: {
    likeMoreFood(state, newFood) {
      state.favoriteFoods.push(newFood)
    },
  },
  actions: {},
  modules: {},
})

To trigger a mutation method a commit is used in a Vue component.

// this.$store.commit("METHOD_NAME", PAYLOAD)
this.$store.commit("likeMoreFood", "🍕")

Keep in mind that all mutations need to be synchronous.

Update State Asynchronously

Asynchronous changes, such as callbacks and fetch requests, are handled by action methods. After an action is finished with an asynchronous task, a mutation can be triggered to update the state.

...
  actions: {
    async asyncLikeMoreFood(context, newFood){
      const fakeFetch = async function() {
      //  Async functions return a Promise
        return "🌯";
      };
      const newFood = await fakeFetch();
      context.commit("likeMoreFood", newFood);
    }
  }
...

Instead of commits, actions are triggered by dispatches in Vue components.

this.$store.dispatch("asyncLikeMoreFood");

React to State Changes

Creating a computed property that returns data from the store state object will cause any elements in the template that uses this computed property to reflect the changes in state.

<template>
  <div id="app">
    {{favoriteFoods}}
  </div>
</template>

<script>
export default {
  name: "App",
  computed: {
    favoriteFoods(){
      return this.$store.state.favoriteFoods;
    }
  }
};
</script>

© Andrew Zamora 2023