The Vuex HopTopics: Getters, Mutations, and Actions
Tags: vue, vuex, javascript
Published: 2020-02-09 01:38:06

##The Vuex Store
Last week we just brushed the surface of Vuex in my tour de force blog [Vuex with Ex-View (cast members)](https://dev.to/iris/vuex-with-ex-view-cast-members-4b7l). In that blog we set up a very basic Vuex store like so:

```javascript
// 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](https://vuex.vuejs.org/guide/modules.html).

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

```javascript
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.](https://dev-to-uploads.s3.amazonaws.com/i/8m21hvppfu05bewkmz3h.png)

##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](https://dev.to/iris/looky-looky-i-wrote-about-hook-s-y-28o7).

```javascript
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.

```javascript
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

```javascript
<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:

* [Vue.js Course on Udemy by Maximilian Schwarzmüller](https://www.udemy.com/course/vuejs-2-the-complete-guide/)
* [Vuex Official Docs](https://vuex.vuejs.org/)