loading...
Cover image for The Vuex HopTopics: Getters, Mutations, and Actions

The Vuex HopTopics: Getters, Mutations, and Actions

iris profile image Iris Silverman ・3 min read

The Vuex Store

Last week we just brushed the surface of Vuex in my tour de force blog Vuex with Ex-View (cast members). In that blog we set up very basic Vuex store like so:

// This is in the store.js file
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex); // enable Vuex functionality in our application

export const store = new Vuex.Store({ // create Vuex Store
  state: {  
    exViewHosts: ['Nicolle Wallace','Lisa Ling','Rosie Perez'], 
    // include properties for your global state here
  }  
}) 

But there is a lot more to the Vuex store than just state. The Vuex store is made up of the global state, as well as Getters, Actions, Mutations, and any Modules you've created to organize the various parts of your store. I won't be covering Modules in this blog, but you can learn more about them in the official Vuex docs Modules section.

Let's now include Getters, Mutations, Actions, and Modules in our Vuex store.

export const store = new Vuex.Store({
  state: {  
    exViewHosts: ['Nicolle Wallace','Lisa Ling','Rosie Perez'], 
  },
  getters: {}, // we'll start filling these out in a moment
  mutations: {},
  actions: {},
  modules: {},
}) 

Diagram of Vuex store with components, state, getters, actions, and mutations. Getters point from the State to the Components, Components point to Actions, Actions point to Mutations, and Mutations point to State.

Getters

Getters are the go between that get (get it?!) access to the global state for the components in your application. If you have experience with React and Redux it might be useful to think of Getters like the mapStateToProps function. If you have experience with React Hooks think of Getters like useSelector (p.s. I wrote a blog about Hooks awhile back that you might be interested in checking out - Looky Looky, I Wrote About Hook(s)y.

export const store = new Vuex.Store({
  state: {  
    // include properties for your global state here
  },
  getters: {
    getExHosts(state) {
      return state.exViewHosts.map(host => host.toUpperCase());
    },
  },
  mutations: {},
  actions: {},
  modules: {},
}) 

Actions and Mutations

When a component needs to change the global state, actions and mutations are the middlemen. You technically don't need Actions to update the global state, but Mutations can only run synchronously while Actions can perform asynchronous changes and so it is best practice to first dispatch an action, then commit the change to your state through a mutation. For those of you with React / Redux experience think of Actions like mapDispatchToProps (for all you Hooks-inators think useDispatch) and mutations are the updates/changes that you make to state in the reducer.

export const store = new Vuex.Store({
  state: {  
    // include properties for your global state here
  },
  getters: {
    getExHosts(state) {
      return state.exViewHosts.map(host => host.toUpperCase());
    },
  },
  mutations: {
    retireHost(state, payload) {
      state.exViewHosts.push(payload.hostName);
    },
  },
  actions: {
    retireHost: ({ commit }, name) => {  
       commit('retireHost', { hostName: name });
    // the Action commits the mutation which will then change the state
    // p.p.s commit is destructured from the action's context object
    // you could also write this as 
    // (context, term) => context.commit(stuff here)  
  },
  },
  modules: {},
}) 

Accessing the Vuex store in your components

There are a couple of helpers for accessing Getters and Actions in your components.

  • mapGetters -- use the spread operator (...) to access in your computed properties
  • mapActions -- use the spread operator to access in your methods
<template>
  <div>
    <ul>
      <li :key="exHost" v-for="exHost in getExHosts">{{ exHost }}</li>
    </ul>
    <button @click="retireHost('Raven-Symoné')">
       That is so NOT Raven
    </button>
  </div>
</template>

<script>
  import { mapGetters, mapActions } from 'vuex';

  export default {
     computed: {
        ...mapGetters([
        'getExHosts'])
        }
     },
     methods: {
        ...mapActions([
        'retireHost'
        ])
     }
  }
</script>

In conclusion...

I've learned a lot about Vuex over the past couple weeks and I hope you have too. I've also learned that I might have an unhealthy obsession with The View, and I hope you do too.

Resources

Here are some great resources that contributed to the growing of my mind grapes:

Posted on by:

iris profile

Iris Silverman

@iris

I switched from a career in customer service as a technical writer, manager, and trainer to pursue coding. Recently graduated from Flatiron School's Full Stack Software Engineering program.

Discussion

markdown guide