Vuex Helper Functions

Use helper functions to access Vuex capabilities and greatly increase readability of your code.

We will consider the following Vuex store for a quick demonstration -

// store/index.js
import Vue from "vue";
import Vuex from "vuex";
import user from "./user";
import account from "./account";

Vue.use(Vuex);

export default new Vuex.Store({
  namespaced: true,
  name: "global",
  modules: {
    user,
    account
  }
});

My user store -

//store/user.js
import axios from "axios";

export default {
  namespaced: true,
  name: "users",
  state: {
    users: [],
    loading: false,
    error: ""
  },
  mutations: {
    setUsers(state, users) {
      state.users = users;
    },
    setLoading(state, loading) {
      state.loading = loading;
    },
    setError(state, error) {
      state.error = error;
    }
  },
  actions: {
    fetchUsers({ commit, state }, params) {
      commit("setLoading", true);
      commit("setError", "");

      axios
        .get("http://myServer.com/api/get-users")
        .then(({ data }) => {
          commit("setUsers", data);
        })
        .catch(e => {
          commit("setError", "Error fetching user records.");
        })
        .finally(commit("setLoading", false));
    }
  }
};

Refer creating modular Vuex post if you do not understand this structure.

After you define a typical store, you can access your store like so -

<!-- User.vue -->
<template>
  {{ users }}
</template>
<script>
  export default {
    computed: {
      users() {
        return this.$store.state.user.users;
      }
    },
    mounted() {
      this.$store.user.dispatch("fetchUsers");
    }
  };
</script>

As you can imagine, using this.$store.state.* gets unreadable too quickly.

Helper functions like mapState, mapGetters, mapActions, and mapMutations make this repetitive code go away. I can access user Vuex store in my view with the following -

<!-- views/User.vue -->
<template>
  <p v-if="error" class="error">{{error }}</p>
  <p>
    {{ users }}
  </p>
</template>

<script>
  import { mapState, mapMutations, mapActions } from "vuex";
  import Panel from "../components/Panel";

  export default {
    computed: {
      ...mapState("user", ["users", "error"])
      // states are now accessible as any other computed property
    },

    methods: {
      ...mapMutations("user", ["setError"]),
      ...mapActions("user", ["fetchUsers"])
      // actions and mutations from store are now accessible
      //   .. as any other methods
    },

    mounted() {
      this.fetchUsers();
    }
  };
</script>
Last updated:
Categories: Vue
Tags: VueJS
comments powered by Disqus