Can I use "this" in mapMutations spread inside Vue instance methods?
Asked Answered
P

3

11

I want to set Vuex mutations as follows:

export default {
    props: {
        store: String
    },
    methods: {
        ...mapMutations({
            changeModel: `${this.store}/changeModel`
        })
    }
}

But I catch the error:

Uncaught TypeError: Cannot read property 'store' of undefined

How do I correctly use props inside the module mutation name?

I want to map this.$store.commit('form1/changeModel'), where form1 is set from props.

Pyrrolidine answered 29/8, 2018 at 19:56 Comment(4)
What's wrong with ...mapMutations(['changeModel'])? Do you want to map this.$store.commit('changeModel') - or something else?Animalize
I want to map this.$store.commit('form1/changeModel'), where form1 is set from props.Pyrrolidine
@Pyrrolidine Why are you using mutations directly in your component instead of actions to begin with?Semiconscious
@BennettDams You're right, actions should be used here.Pyrrolidine
F
3

Vuex helper mapMutations can be used with a function which works with this.

There does not seem to be a doc for this, but the Vuex unit test helpers.spec.js illustrates the pattern.

const vm = new Vue({
  store,
  methods: mapMutations({
    plus (commit, amount) {
      commit('inc', amount + 1)
    }
  })
})

As a bonus, the function allows passing a parameter to the mutation, which is a common requirement.

Your code changes would be:

export default {
  props: {
    store: String
  },
  methods: {
    ...mapMutations({
      changeModel(commit) { commit(`${this.store}/changeModel`) }
    })
  }
}

The call within your component is just changeModel() - mapMutations is taking care of injecting the commit parameter.

Note, I am not sure this is adding much except some extra noise (compared to a simple this.$store.commit()), but perhaps your requirement is more complicated than the example code.

Furrow answered 3/9, 2018 at 23:36 Comment(2)
Very nice. If you have the time, this would be a good documentation feature request to add to their issues list.Rigidify
the API guide for mapMutations does introduce this.Crest
M
3

I think there is no way to bind this on mapActions. But you can call it with $store.dispatch

methods: {
  changeModel() {
    this.$store.dispatch(`${this.store}/changeModel`);
  }
}
Mohler answered 31/8, 2018 at 2:18 Comment(1)
or even this.$store.commit() which is what you would use for a mutationRigidify
F
3

Vuex helper mapMutations can be used with a function which works with this.

There does not seem to be a doc for this, but the Vuex unit test helpers.spec.js illustrates the pattern.

const vm = new Vue({
  store,
  methods: mapMutations({
    plus (commit, amount) {
      commit('inc', amount + 1)
    }
  })
})

As a bonus, the function allows passing a parameter to the mutation, which is a common requirement.

Your code changes would be:

export default {
  props: {
    store: String
  },
  methods: {
    ...mapMutations({
      changeModel(commit) { commit(`${this.store}/changeModel`) }
    })
  }
}

The call within your component is just changeModel() - mapMutations is taking care of injecting the commit parameter.

Note, I am not sure this is adding much except some extra noise (compared to a simple this.$store.commit()), but perhaps your requirement is more complicated than the example code.

Furrow answered 3/9, 2018 at 23:36 Comment(2)
Very nice. If you have the time, this would be a good documentation feature request to add to their issues list.Rigidify
the API guide for mapMutations does introduce this.Crest
C
1

It is not exaclty the solution that you asked but its effect is the same. As the mutation is a variable parameter, it is obvious to put it into a function as an input parameter instead of changing the mutation name. I would create an action in the store like this:

changeModel ({dispatch, commit, rootGetters}, mutationName) {
 commit(`${mutationName}/changeModel`, {}, {root: true})
})

And I would use this action in the component passing the mutationName into it.

Cam answered 5/9, 2018 at 8:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.