Vuex 4 — Mutations
Tags: vue, webdev, programming, javascript
Published: 2021-01-26 01:20:14

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**


**Vuex 4 is in beta and it’s subject to change.**

Vuex is a popular state management library for Vue.

Vuex 4 is the version that’s made to work with Vue 3.

In this article, we’ll look at how to use Vuex 4 with Vue 3.

### Object-Style Commit

We can pass in an object to the `commit` method.

For example, we can write:

```
<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://unpkg.com/vuex@4.0.0-beta.4/dist/vuex.global.js"></script>
    <title>App</title>
  </head>
  <body>
    <div id="app">
      <button @click="decrement">decrement</button>
      <p>{{count}}</p>
    </div>
    <script>
      const store = new Vuex.Store({
        state: {
          count: 0
        },
        mutations: {
          decrement(state, payload) {
            state.count -= payload.amount;
          }
        }
      });
      const app = Vue.createApp({
        methods: {
          decrement() {
            this.$store.commit({
              type: "decrement",
              amount: 5
            });
          }
        },
        computed: {
          count() {
            return this.$store.state.count;
          }
        }
      });
      app.use(store);
      app.mount("#app");
    </script>
  </body>
</html>
```

We pass in an object into the `this.$store.commit` method.

Properties other than `type` would end up in the `payload` object.

So we can access the `amount` property with `payload.amount` in the `decrement` mutation method.

Mutations follow Vue 3’s reactivity rules, so whenever a reactive state variable is updated, the store state will change.

### Using Constants for Mutation Types

We can use constants for mutation types.

For example, we can write:

```
<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://unpkg.com/vuex@4.0.0-beta.4/dist/vuex.global.js"></script>
    <title>App</title>
  </head>
  <body>
    <div id="app">
      <button @click="decrement">decrement</button>
      <p>{{count}}</p>
    </div>
    <script>
      const DECREMENT = "decrement";

      const store = new Vuex.Store({
        state: {
          count: 0
        },
        mutations: {
          [DECREMENT](state) {
            state.count -= 1;
          }
        }
      });
      const app = Vue.createApp({
        methods: {
          decrement() {
            this.$store.commit(DECREMENT);
          }
        },
        computed: {
          count() {
            return this.$store.state.count;
          }
        }
      });
      app.use(store);
      app.mount("#app");
    </script>
  </body>
</html>
```

We passed in a `DECREMENT` constant which we passed in as the name of the mutation in the `mutations` property and the `commit` method.

It’s useful for reusing the same name in multiple places.

### Mutations Must Be Synchronous

Mutations must be synchronous.

This is because the code inside it must run in sequence so that we can trace the code.

### Committing Mutations in Components

We can call the `mapMutations` method to map our mutations to a method.

For example, we can write:

```
<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://unpkg.com/vuex@4.0.0-beta.4/dist/vuex.global.js"></script>
    <title>App</title>
  </head>
  <body>
    <div id="app">
      <button @click="decrement">decrement</button>
      <p>{{count}}</p>
    </div>
    <script>
      const store = new Vuex.Store({
        state: {
          count: 0
        },
        mutations: {
          decrement(state) {
            state.count -= 1;
          }
        }
      });
      const app = Vue.createApp({
        methods: {
          ...Vuex.mapMutations(["decrement"])
        },
        computed: {
          count() {
            return this.$store.state.count;
          }
        }
      });
      app.use(store);
      app.mount("#app");
    </script>
  </body>
</html>
```

to call the `Vuex.mapMutations` method to a method.

Then we can run that when we click the decrement button.

Payloads are supported when we map mutations with `mapMutations` .

We can map a mutation to a method with a different name with:

```
<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://unpkg.com/vuex@4.0.0-beta.4/dist/vuex.global.js"></script>
    <title>App</title>
  </head>
  <body>
    <div id="app">
      <button @click="subtract">decrement</button>
      <p>{{count}}</p>
    </div>
    <script>
      const store = new Vuex.Store({
        state: {
          count: 0
        },
        mutations: {
          decrement(state) {
            state.count -= 1;
          }
        }
      });
      const app = Vue.createApp({
        methods: {
          ...Vuex.mapMutations({
            subtract: "decrement"
          })
        },
        computed: {
          count() {
            return this.$store.state.count;
          }
        }
      });
      app.use(store);
      app.mount("#app");
    </script>
  </body>
</html>
```

We mapped the `decrement` mutation to the `subtract` method with the key of the object we passed into `mapMutations` .

### Conclusion

We can create and mutations in various to change Vuex state data.