use `mapActions` or `mapGetters` with Vuex 4 and Vue 3

Viewed 14599

Anybody knows how to use mapState or mapGetters with Vue 3 in the setup function ? I know that is possible to use the store with the useStore hook but with this hook We import all the store while with mapState or mapGetters we can specify a module :

// ...

computed: {
   ...mapGetters('myModule', [
      'myStateVariable'
   ]
) 

//...
4 Answers

As far as I can tell, they get flattened so you can't use myModule/myStateVariable, but myStateVariable should work.

This could be something that may change as Vuex gets to RC releases, but for now if you try to have the same getter twice, you get this error

enter image description here

Perhaps something like this:

import { computed }  from 'vue';
import { useStore } from 'vuex';

const module = 'myModule';

export default {
    setup() {
        const store = useStore();

        return {
            // getter
            one: computed(() => store.getters[`${module}/myStateVariable`],

            // state
            two: computed(() => store.state[module].myStateVariable,
        };
    },
};

With vue 3 and vuex 4 I managed to do it like this: suppose we have a store shown below:

enter image description here

our general store index.js (the one on the bottom) would be like this:

 import { createStore,     createLogger   } from 'vuex';
 import module1 from '@/store/module1';
 import module2 from '@/store/module2';


 export default createStore({

 modules: {
    module1: module1,
    module2: module2,
 },
  plugins: process.env.NODE_ENV !== 'production'
  ? [createLogger()]
  : []
})

whereas the modules would each have such an index.js:

import * as getters from './getters'
import * as actions from './actions'
import mutations from './mutations'


const state = {
  postId: 10111,
}

export default {
  namespaced: true,

  state,
  getters,
  actions,
  mutations,
  
}

and the getter in each one of the module would be like this:

export const getPostId = state => {
   return state.postId 
}

finally in a component you could access the getters like that:

<template>
 <div>
   <div class="major_container">
     <p>{{ postIdFromModule1 }}</p>
     <p>{{ postIdFromModule2 }}</p>
  </div>
</div>
</template>
<script> 
import { computed } from "vue";
import { useStore } from "vuex";

export default {
 setup() {
   const store = useStore();

   const postIdFromModule1 = computed(() => store.getters["module1/getPostId"]);
   const postIdFromModule2 = computed(() => store.getters["module2/getPostId"]);

   return {
     postIdFromModule1,
     postIdFromModule2,
   };
  },
};
</script>

Great, now you can use the modules namespaced!

The best way to use mapActions in a vue3 style SFC is to use mapActions in the setup() function's return

import { mapActions } from "vuex"
setup() {
  return {
    ...mapActions("myModule", ["doSomething"])
  }
}
Related