Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Differences b/n mapState, mapGetters, mapActions, mapMutations in Vuex

I have been using vue/vuex for months and I see mapState, mapGetters, mapActions, mapMutations but don't know what they do except for mapState.

This is how I use mapState

// mutations.js 
user: {
   address: {},
   name: '',
   age: ''
}

and in my code I have something like this:

import { mapState } from 'vuex'
export default {
  data: {},

  computed: {
   ...mapState({
    address: state => state.user.address
   })
  }
} 

then I can use address anywhere, but I don't know what the others are used for.

can someone give a simple example? thanks

like image 828
hidar Avatar asked Apr 06 '18 15:04

hidar


People also ask

What is the use of mapState in VUEX?

Mapping in Vuex enables you to bind any of the state's properties, like getters, mutations, actions, or state, to a computed property in a component and use data directly from the state. Although we can get the job done with this. $store.state.user.data.name , we can use a map helper to simplify it to this.

What is mapActions VUEX?

In Vuex, actions are (usually) asynchronous operations which carry out mutations, as opposed to direct updates to the state. mapActions is just a helper that lets you call those methods from within a Vue component.

What is mapGetters VUEX?

Mapping getters is similar to mapping state. Getters provide a way of getting a derived computed state from the store e.g a function that returns products based on popularity. Vuex also provides a mapGetters helper function to map getters to local computed properties.

What is mapState in VueJS?

Mapping State Vuex provides a helper function called mapState to solve this problem. It is used for mapping state properties in the store to computed properties in our components. import { mapState } from 'vuex' export default{ computed: { ... mapState([ 'products','product','cart','notifications' ]) } }


1 Answers

None of those mappers are mandatory. Their goal is just to make easy to create computed properties or methods in the components. They are DRY (avoid duplication) at its best.

mapState is a helper that simplifies creating a computed property that reflects the value of a given state.

Similarly:

  • mapGetters is a helper that simplifies creating a computed property that reflects the value returned by a given getter.
    • Note that even method-style getters should be mapped to computed properties.
  • mapActions is a helper that simplifies creating a method that would be equivalent as calling dispatch on an action.
  • mapMutations is a helper that simplifies creating a method that would be equivalent as calling commit on an mutation.

Since code helps, the demo below shows examples of using all those mappers, and their equivalent without mappers. Their behavior is exactly the same. The mappers just allow you to write with less code (consider that this will be repeated in many, many components of your app).

const store = new Vuex.Store({
  strict: true,
  state: {name: "John"},
  mutations: {
  	changeName(state, data) {
    	state.name = data
    }
  },
  actions: {
    fetchRandomName({ commit }) {
      let randomId = Math.floor(Math.random() * 12) + 1  ;
      axios.get("https://reqres.in/api/users/" + randomId).then(response => {
        commit('changeName', response.data.data.first_name)
      })
    }
  },
  getters: {
    getName: state => state.name,
    getTransformedName: (state) => (upperOrLower) => {
      return upperOrLower ? state.name.toUpperCase() : state.name.toLowerCase()
    }
  }
});
new Vue({
  store,
  el: '#app',
  data: { newName: 'Bob' },
  computed: {
    ...Vuex.mapState(['name']),
    nameNoMapper() { return this.$store.state.name },
    ...Vuex.mapGetters(['getName', 'getTransformedName']),
    getNameNoMapper() { return this.$store.getters.getName },
    getTransformedNameNoMapper() { return this.$store.getters.getTransformedName }
  },
  methods: {
    ...Vuex.mapActions(['fetchRandomName']),
    ...Vuex.mapMutations(['changeName']),
    fetchRandomNameNoMapper() { this.$store.dispatch('fetchRandomName') },
    changeNameNoMapper(newName) { this.$store.commit('changeName', newName) },
  }
})
table, tr, td {
  font-family: monospace;
  border: 1px solid black;
  border-collapse: collapse;
}
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vuex"></script>
<script src="https://unpkg.com/[email protected]/dist/axios.min.js"></script>

<div id="app">
  <table>
    <tr>
      <td style="width: 250px">With Mappers</td>
      <td style="width: 310px">Without Mappers</td>
    </tr>
    <tr>
      <td>
        name: {{ name }}<br>
        getName: {{ getName }}<br>
        getTransformedName(true): {{ getTransformedName(true) }}<br>
        getTransformedName(false): {{ getTransformedName(false) }}
      </td>
      <td>
        nameNoMapper: {{ nameNoMapper }}<br>
        getNameNoMapper: {{ getNameNoMapper }}<br>
        getTransformedNameNoMapper(true): {{ getTransformedNameNoMapper(true) }}<br>
        getTransformedNameNoMapper(false): {{ getTransformedNameNoMapper(false) }}
      </td>
    </tr>
  </table>
  <hr>
  <button @click="fetchRandomName">ACTION: fetchRandomName</button> - <button @click="fetchRandomNameNoMapper">ACTION: fetchRandomNameNoMapper</button><br>
  <hr>
  <input v-model="newName"><button @click="changeName(newName)">MUTATION: changeName</button><button @click="changeNameNoMapper(newName)">MUTATION: changeNameNoMapper</button>
</div>
like image 185
acdcjunior Avatar answered Dec 08 '22 05:12

acdcjunior