DEV Community

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

The Vuex HopTopics: Getters, Mutations, and Actions

iris profile image Iris Silverman Updated on ・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 a 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
  }  
}) 
Enter fullscreen mode Exit fullscreen mode

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: {},
}) 
Enter fullscreen mode Exit fullscreen mode

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: {},
}) 
Enter fullscreen mode Exit fullscreen mode

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: {},
}) 
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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:

Discussion

pic
Editor guide