Categories
Vue 3

Vuex 4 — Mutations

Spread the love

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.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *