How to Use Axios with Vuex

John Au-Yeung - Jan 26 '21 - - Dev Community

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 is a state management library for Vue apps.

It’s the most popular choice for state management for Vue apps.

In this article, we’ll look at how to use the Axios HTTP client with Vuex.

Run Async Code with Actions

We can run async code in a Vuex store within actions.

To add an action, we just add the action property into the object we pass into the Vuex.Store constructor.

For example, we can write:

main.js

import Vue from "vue";
import App from "./App.vue";
import Vuex from "vuex";

Vue.config.productionTip = false;
Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  actions: {
    increment(context) {
      context.commit("increment");
    }
  }
});

new Vue({
  store,
  render: (h) => h(App)
}).$mount("#app");
Enter fullscreen mode Exit fullscreen mode

to add the actions property with the increment method.

The context.commit method commits the mutation we want to change the state.

Then we can dispatch the action in our component with the this.$store.dispatch method:

App.vue

<template>
  <div id="app">
    <button @click="increment">increment</button>
    <p>{{count}}</p>
  </div>
</template>

<script>
export default {
  name: "App",
  computed: {
    count() {
      return this.$store.state.count;
    }
  },
  methods: {
    increment() {
      this.$store.dispatch("increment");
    }
  }
};
</script>
Enter fullscreen mode Exit fullscreen mode

Since actions can have async code in it, we can just add the async code we want in the action method.

The code can update the state.

To use Axios to make a request in our action, we write:

main.js

import Vue from "vue";
import App from "./App.vue";
import Vuex from "vuex";
import axios from "axios";

Vue.config.productionTip = false;
Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    post: {}
  },
  mutations: {
    setPost(state, data) {
      state.post = data;
    }
  },
  actions: {
    async getPost(context, { id }) {
      const { data } = await axios.get(
        `https://jsonplaceholder.typicode.com/posts/${id}`
      );
      context.commit("setPost", data);
    }
  }
});

new Vue({
  store,
  render: (h) => h(App)
}).$mount("#app");
Enter fullscreen mode Exit fullscreen mode

App.vue

<template>
  <div id="app">
    <button @click="getPost">get post</button>
    <p>{{post}}</p>
  </div>
</template>

<script>
export default {
  name: "App",
  computed: {
    post() {
      return this.$store.state.post;
    }
  },
  methods: {
    getPost() {
      this.$store.dispatch("getPost", { id: 1 });
    }
  }
};
</script>
Enter fullscreen mode Exit fullscreen mode

The difference is that we have the getPost async method to make the request to the API.

Then once we have the result, we call context.commit to commit the setPost mutation to update the state.

In the setPost mutation method, we get the data parameter’s value and then set it as the value of state.post to update the post state.

In App.vue , we dispatch the getPost action with the this.$store.dispatch method the same way. 

Just that we add an object with the id property to pass it to the getPost action method as the 2nd parameter.

In the post computed property, we return the value of the this.$store.state.post property.

Now when we click the get post button, we should see the post data displayed from the post state via the post computed property.

Conclusion

We can use Axios with Vuex as long as we put the Axios code in the Vuex store action.

An action method can have async code but mutations can’t.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .