Search code examples
vue.jsvuejs2vue-componentvuexvuex-modules

Access module from Vuex Store


I have the following module:

export const ProfileData = {
    state: {
        ajaxData: null;
    },
    getters: {/*getters here*/},
    mutations: {/*mutations here*/},
    actions: {/*actions here*/}
}

and this module is registered in my global store:

import {ProfileData} from './store/modules/ProfileData.es6'
const store = new Vuex.Store({
    modules: {
       ProfileData: ProfileData
    }
});

I have also used the Vue.use(Vuex) and set the store in new Vue({ store: store}) properly. However, when I try to access the ajaxData belonging to the ProfileData module, in one of my components via this.$store.ProfileData.ajaxData, the console shows an undefined error. The same goes for reading the this.$store.ProfileData or this.$store.ajaxData, while this.$store is defined and I am already able to read it. I also see the ProfileData object added to the _modules property of the store in browser's console.

What is that I am doing wrong to access the modules registered to the Vuex? How can I access those?


Solution

  • Directly accessing state of Vuex module

    The format to access a Module's local state is $store.state.moduleName.propertyFromState.

    So you would use:

    this.$store.state.ProfileData.ajaxData
    

    Demo:

    const ProfileData = {
      state: {ajaxData: "foo"}
    }
    const store = new Vuex.Store({
      strict: true,
      modules: {
        ProfileData
      }
    });
    new Vue({
      store,
      el: '#app',
      mounted: function() {
      	console.log(this.$store.state.ProfileData.ajaxData)
      }
    })
    <script src="https://unpkg.com/vue/dist/vue.min.js"></script>
    <script src="https://unpkg.com/vuex"></script>
    
    <div id="app">
      <p>ajaxData: {{ $store.state.ProfileData.ajaxData }}</p>
    </div>


    Getters, Actions and Mutators of modules, how to directly access them?

    It depends if they are namespaced or not. See demo (explanation in comments):

    const ProfileDataWithoutNamespace = {
      state: {ajaxData1: "foo1"},
      getters: {getterFromProfileDataWithoutNamespace: (state) => state.ajaxData1}
    }
    const ProfileDataWithNamespace = {
      namespaced: true,
      state: {ajaxData2: "foo2"},
      getters: {getterFromProfileDataWithNamespace: (state) => state.ajaxData2}
    }
    const store = new Vuex.Store({
      strict: true,
      modules: {
        ProfileDataWithoutNamespace,
        ProfileDataWithNamespace
      }
    });
    new Vue({
      store,
      el: '#app',
      mounted: function() {
        // state is always per module
      	console.log(this.$store.state.ProfileDataWithoutNamespace.ajaxData1)
        console.log(this.$store.state.ProfileDataWithNamespace.ajaxData2)
        // getters, actions and mutations depends if namespace is true or not
        // if namespace is absent or false, they are added with their original name
        console.log(this.$store.getters['getterFromProfileDataWithoutNamespace'])
        // if namespace is true, they are added with Namespace/ prefix
        console.log(this.$store.getters['ProfileDataWithNamespace/getterFromProfileDataWithNamespace'])
      }
    })
    <script src="https://unpkg.com/vue/dist/vue.min.js"></script>
    <script src="https://unpkg.com/vuex"></script>
    
    <div id="app">
      <p>Check the console.</p>
    </div>