When we used VUex, the mutation and action methods were very close, today I will talk about the characteristics and differences of the two methods. This is my second article as a novice

Function and Usage

mutation

We know that when managing project state with VUex, you can only make state changes in the Store using COMMIT to commit mutation

Mutations in Vuex are very similar to events: each mutation has an event type (type) of a string and a callback function (handler). This callback function is where we actually make the state change, and it takes state as the first argument:

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment (state) {
      // Change the status
      state.count++
    }
  }
})
// You cannot call an mutation Handler directly. This option is more like event registration: "This function is called when a mutation of type Increment is triggered." To wake up an mutation Handler, you need to call the store.com MIT method with the appropriate type:
store.commit('increment')   
Copy the code

The rest of the uses of mutation will not be detailed, but the limitations of mutation will be discussed

Mutation must be a synchronization function

Why does mutation have to be a synchronous function? What happens to mutation if asynchrony is added?

mutations: {
  someMutation (state) {
    api.callAsyncMethod(() = > {
      state.count++
    })
  }
}
Copy the code

Notice that in the above code, the mutation has been added to the asynchronous processing function. Mutation can be used normally, but we need to look at the mutation log in DevTool when we debug in our daily development. Theoretically, mutation takes one step and Devtool records another, but adding an asynchronous function to mutation causes our Devtool record to fail because devTool doesn’t know when and where your asynchronous function is called

Action

Action is similar to mutation, except that:

  • The Action commits the mutation instead of directly changing the state.
  • An Action can contain any asynchronous operation.
const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      context.commit('increment')}}})Copy the code

The Action function takes a context object that has the same methods and properties as the Store instance, so you can call context.com MIT and submit a mutation, Or get state and getters from context.state and context.getters.

In practice, we often use ES2015’s new window to simplify code (especially if we need to call commit many times) :

actions: {
  increment ({ commit }) {
    commit('increment')}}Copy the code

Distribution of the Action

Action is triggered by the store.dispatch method:

store.dispatch('increment')
Copy the code

At first glance, it seems unnecessary. Wouldn’t it be more convenient for us to just distribute mutation? In fact, no, remember that mutation must execute this restriction synchronously? Action is free! We can perform asynchronous operations within an action:

actions: {
  incrementAsync ({ commit }) {
    setTimeout(() = > {
      commit('increment')},1000)}}Copy the code

Actions supports the same payload and object distribution:

// Distribute as a payload
store.dispatch('incrementAsync', {
  amount: 10
})

// Distribute as objects
store.dispatch({
  type: 'incrementAsync'.amount: 10
})
Copy the code

Take a more realistic example of a shopping cart, involving calling the asynchronous API and distributing multiple mutations:

actions: {
  checkout ({ commit, state }, products) {
    // Back up the current shopping cart
    const savedCartItems = [...state.cart.added]
    // Make a checkout request, and then optimistically empty the cart
    commit(types.CHECKOUT_REQUEST)
    // The shopping API accepts a success callback and a failure callback
    shop.buyProducts(
      products,
      // The operation succeeded
      () = > commit(types.CHECKOUT_SUCCESS),
      // Failed operation
      () = > commit(types.CHECKOUT_FAILURE, savedCartItems)
    )
  }
}
Copy the code

Note that we are doing a series of asynchronous operations and that we are recording the side effects (state changes) from the action by submitting the mutation.

In short, where mutation cannot complete asynchrony, action will do it for you! Mutation cannot record records, action to help you split records!