vue.jsvuexnuxt.jsvuex-modules

how to get nested getters in vuex nuxt


i have store/index.js like this

new Vuex.Store({
  modules: {
    nav: {
      namespaced: true,
      modules: {
        message: {
          namespaced: true,
          state: {
            count: 0,
            conversations: [],
          },
          getters: {
            getCount: state => {
              return state.count;
            },
          },
          mutations: {
            updateCount(state) {
              state.count++;
            },
          },
          actions: {},
        },
        requests: {
          namespaced: true,
          state: {
            friends: [],
          },
          getters: {
            getFriends: state => {
              return state.friends;
            },
          },
          mutations: {
            pushFriends(state, data) {
              state.friends.push(data);
            },
          },
          actions: {
            pushFriends(commit, data) {
              commit('pushFriends', data);
            },
          },
        },
      },
    },
  },
});

i want to use getters in computed property i have tested like this

computed: {
    ...mapGetters({
      count: 'nav/message/getCount',
    }),
  },

butt getting error

[vuex] unknown getter: nav/message/getCount

what is am missing here

i also want to make separate folder for every modules like my nav have 3 modules message, requests & notifications

i did try but nuxt blow up my codes


Solution

  • I think your index is wrong, the correct thing is to separate the modules independently, something like this:

    in your store/index.js

        export const state = () => ({
          config: {
            apiURL: 'https://meuapp.com'
          }
        })
        
        export const mutations = { }        
        export const actions = { }
    
        // getters
        export const getters = { 
          test: state => payload => {
            if (!payload)
              return {
                message: 'this is an messagem from index without payload test.', // you don't need pass any payload is only to show you how to do.
                result: state.config
              }
            else 
              // return value
              return {
                message: 'this is an message from index test with payload.',
                result: state.config, // here is your index state config value
                payload: payload // here is yours params that you need to manipulate inside getter
              }
          } 
        }
    
    

    here is your store/navi.js

        export const state = () => ({
          navi: {
            options: ['aaa', 'bbb', 'ccc']
          }
        })
    
        export const mutations = { }
        export const actions = { }
        
        // getters
        export const getters = { 
          test: state => payload => {
            if (!payload)
              return {
                message: 'this is a messagem from nav store without payload test.', // you don't need pass any payload is only to show you how to do.
                result: state.navi
              }
            else 
              // return value
              return {
                message: 'this is an messagem from navi test with payload.',
                result: state.navi, // here is your index state config value
                payload: payload // here is yours params that you need to manipulate inside getter
              }
          } 
        }
        
    

    then in your component you can use as a computed properties:

        <template>
          <div>
            without a paylod from index<br>
            <pre v-text="indexTest()" />
        
            with a paylod from index<br>
            <pre v-text="indexTest( {name: 'name', other: 'other'})" />
        
            without a paylod from navi<br>
            <pre v-text="naviTest()" />
        
            with a paylod from navi<br>
            <pre v-text="naviTest( {name: 'name', other: 'other'})" />
        
            access getters from methods<br>
            <pre>{{ accessGetters('index') }}</pre>
            <pre v-text="accessGetters('navi')" />
            <br><br>
        
          </div>
        </template>
        
        <script>
        import {mapGetters} from 'vuex'
        export default {
          computed: {
            ...mapGetters({
              indexTest: 'test',
              naviTest: 'navi/test'
            })
          },
          methods: {
            accessGetters (test) {
              if (test && test === 'index' ) {
                console.log('test is', test) // eslint-disable-line no-console
                return this.indexTest()
              }
              else if (test && test === 'navi') {
                console.log('test is:', test) // eslint-disable-line no-console
                return this.naviTest()
              }
              else {
                return 'test is false'
              }
            }
          }
        }
        </script>
    

    Whenever possible separate your code into smaller parts, one part for each thing. This makes it easier for you to update and keep everything in order.

    Hope this helps.