How to access Vuex module getters and mutations?
Asked Answered
M

9

80

I'm trying to switch to using Vuex instead of my homegrown store object, and I must say I'm not finding the docs as clear as elsewhere in the Vue.js world. Let's say I have a Vuex module called 'products', with its own state, mutations, getters, etc. How do I reference an action in that module called, say, 'clearWorking Data'? The docs give this example of accessing a module's state:

store.state.a // -> moduleA's state

But nothing I can see about getters, mutations, actions, etc.

Minne answered 24/1, 2017 at 16:31 Comment(2)
Agree: the docs for vuex are abysmal. Really not helpful.Turtleneck
@Turtleneck i've definitely noticed areas that could be better. Have you considered raising an issue on GitHub with suggested improvements?Wellesley
R
42

In your example it would be store.dispatch('products/clearWorkingData') you can think of actions/mutations as a file system in a way. The deeper the modules are nested the deeper in the tree they are.

so you could go store.commit('first/second/third/method') if you had a tree that was three levels deep.

Roryros answered 24/1, 2017 at 16:37 Comment(4)
Ah, OK! Is this dependent on setting namespaced: true?Minne
@JohnMoore Yes sorry for not mentioning it, any module you want to have separated needs to have namespaced: true, set. if not then it'll inherit the namespace of the parent module.Roryros
@JustinMacArthur does this method of accessing data from a module within a vuex store also work if you are trying to access it from within the composition api setup() method?Froward
@PA-GW This was written for V2.x and the appropriate Vuex. I'm not sure if it would work with the composition api. I don't see why not depending on execution time.Roryros
S
189

In Addition to the accepted answer I wanna provide you with a workarround for the getter which is missing in the answer.

Debug the Store
In any case you can call console.log(this.$store) to debug the Store.
If you do so you will see the getters are prefixed with the namespace in their name. enter image description here

Access namespaced getter

this.$store.getters['yourModuleName/someGetterMethod']

Dispatch namespaced

this.$store.dispatch('yourModuleName/doSomething')

Dispatch namespaced with params

this.$store.getters['yourModuleName/someGetterMethod'](myParam)

Conclusion
The key is to handle the namespace like a file System like Justin explained.

Edit: found a nice library for handling vuex Store
In addition to the basic knowledge I'd like to add this vuex library as a nice addition for working effectivly and fast with the vuex store. https://github.com/davestewart/vuex-pathify .
It looks pretty interesting and cares much of the configuration for you and also allows you to handle 2waybinding directly with vuex.

** Edit: Thanks to the other Answers. Added Dispatching method with params for wholeness.

Seabrooke answered 9/7, 2017 at 18:9 Comment(8)
So where I was using return store.getters.individuals before adding namespaced=true, I now have to use return store.getters['individual/individuals'] Thank you for this additional answer. Spent half an hour on this and found zero examples of accessing the namespaced getter until your answer here.Ternate
The reason for the change should have been obvious to me. You can't use dot notation for a property with a name that includes special characters like '/', so you have to use bracket notation. could use bracket notation in all cases, it's just not as elegant. So dot notation is often used unless it can't be like in this example.Ternate
Don't forget to set namespaced: true in each of your module, to be able to use getters like that.Esquibel
Thank you for complementing the getters part that was not exposed in the accepted answer...you made my dayGelding
Access namespaced getter! YES! Thank you! Why?.. Why they didn't include this in documentation? 🤦🏻‍♂️Ellinger
how can pass payload in namespaced dispatch?Spinney
See updated Post or next Answer below. this.$store.getters['yourModuleName/someGetterMethod'](myParam)Seabrooke
@Ternate the obvious answer is the one that i'm sure we all tried first and didn't work getters.namespace,function, so then you look at the manual and see "Getters are also registered in the global namespace by default. However, this currently has no functional purpose" so there must be the approved way of accessing but seems to be completely absent from the manual, though im guessing the approved method is $store.modules.name.gettersTeutonism
R
42

In your example it would be store.dispatch('products/clearWorkingData') you can think of actions/mutations as a file system in a way. The deeper the modules are nested the deeper in the tree they are.

so you could go store.commit('first/second/third/method') if you had a tree that was three levels deep.

Roryros answered 24/1, 2017 at 16:37 Comment(4)
Ah, OK! Is this dependent on setting namespaced: true?Minne
@JohnMoore Yes sorry for not mentioning it, any module you want to have separated needs to have namespaced: true, set. if not then it'll inherit the namespace of the parent module.Roryros
@JustinMacArthur does this method of accessing data from a module within a vuex store also work if you are trying to access it from within the composition api setup() method?Froward
@PA-GW This was written for V2.x and the appropriate Vuex. I'm not sure if it would work with the composition api. I don't see why not depending on execution time.Roryros
C
30

As another addition to the accepted answer, if you need to pass parameter(s) to the getter (for instance to fetch a specific item from the store collection), you need to pass it as follows:

this.$store.getters['yourModuleName/someGetterMethod'](myParam)

I don't think I like this notation very much, but it is what it is - at least for the moment.

Contraception answered 10/2, 2019 at 9:1 Comment(1)
Using Vuex4, in setup of composition api, I added the following. setup(props) { const store = useStore() const randomNumber = computed(() => store.getters['item/getRandomNumber']) return { randomNumber }; }, But getting lint error: @typescript-eslint/no-unsafe-member-access: Unsafe member access ['item/getRandomNumber'] on an any value.Quatrain
S
22

Try this approach!

getCounter(){
  return this.$store.getters['auth/getToken'];     
}

auth is my module name and getToken is my getter.

Streaming answered 14/3, 2020 at 8:38 Comment(0)
F
15

Using Vuex mapGetters and mapActions you can now do this pretty easily. But I agree, it still isn't very obvious in the documentation.

Assuming your store module 'products' has a getter called 'mostPopular' and an action called 'clearWorkingData':

<template>
 <div>
  <p>{{mostPopularProduct}}<p>
  <p><button @click="clearProductData">Clear data</button></p>
 </div>
</template>
<script>
import { mapGetters, mapActions } from "vuex";

export default {
 computed: mapGetters({
  mostPopularProduct: "products/mostPopular"
 }),
 methods: mapActions({
  clearProductData: "products/clearWorkingData"
 })
}
</script>
Fax answered 19/4, 2019 at 18:19 Comment(0)
T
1

The mapGetters helper simply maps store getters to local computed properties:

    import { mapGetters } from 'vuex'

    export default {
  // ...
  computed: {
    // mix the getters into computed with object spread operator
    ...mapGetters([
      'doneTodosCount',
      'anotherGetter',
      // ...
    ])
  }
}
If you want to map a getter to a different name, use an object:

    ...mapGetters({
  // map `this.doneCount` to `this.$store.getters.doneTodosCount`
  doneCount: 'doneTodosCount'
})
Tankoos answered 22/5, 2019 at 4:38 Comment(1)
This doesn't account for the core of the question: how to access a specific vuex module's getterCurtice
P
1

You have to be aware of using namespaced: true when configuring particular store object

Phyle answered 20/6, 2021 at 14:45 Comment(0)
L
0

In Addition to the accepted answer, I feel it's not a good idea to mutate the state and commit the mutation directly in component. Thumb rule I follow is, Always use an action to commit the mutation and state only mutate inside mutations. Use getters to get a transformed state.

Getters can be mapped to computed using mapGetters and actions can be mapped to methods using mapActions as below example

// component.vue
// namespace_name=products

<template>
  <div>
    <p> This is awesome product {{getRecentProduct}} </p>
  </div>
  <button @click="onButtonClick()"> Clear recent</button>
</template>
<script>
import { mapGetters, mapActions } from "vuex";

export default {
  computed: {
    ...mapGetters({
        getRecentProduct: "products/getRecentProduct",
    }),
    anotherComputed(){
        return "anotherOne"
    }
  },
  methods: {
     ...mapActions({
        clearRecentProduct: "products/clearRecentProduct",
    }),
    onButtonClick(){
        this.clearRecentProduct(); /// Dispatch the action 
    },
    anotherMethods(){
        console.log(this.getRecentProduct); // Access computed props
    }
  }
};
</script>

Labial answered 9/11, 2022 at 11:21 Comment(0)
N
0

Here's how you can access vuex Getters & Mutations using Composition API (setup)

<script setup>
import { useStore } from 'vuex'

const store = useStore();

var value = store.getters['subModuleName/getterMethod'];

store.commit['subModuleName/MutationMethod'];

</script>
Noway answered 3/12, 2022 at 3:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.