actions

Vuex offers a great way to mutate state items with the use of mutations and actions. Vuex-asr enables you to bind those actions and mutations the same way you could bind state and getters by the component's attributes. In this chapter we discuss the use of actions.

codesandbox

actions

vuex actions in a nutshell

Actions are methods in the store used for asynchronous interaction of data, typically triggered by an event, like fetching data from an API and commit the received data as a mutation to mutate the state. You could make multiple commits in an action and you have access to all of the state and mutations in the store (and it's namespaces).

TIP

Keeping track of mutations (e.g. triggered by actions) is very handy for debugging. It's recommended to download the vue.js devtools for chrome. If you go to the Vuex tab in it you'll see your mutations and state.

You could read more about actions in the vuex guide/actions.

when to use a mutation or an action

This convention could help you to decide to use mutations or actions:

  • if you are updating a single state item, you could use a mutation, but more elegantly it would be to create an action that commits a mutation.
  • If you have to update multiple state items or have an asynchronous procedure in one method you should always use an action.

the store

Let's take a look at the following store,





 


 
 
 
 


 
 
 
 
 
 



// src/vuex/store.js

export default new Vuex.Store({
  state: {
    message: "message in the root of the store",
  },
  mutations: {
    setMessage(state, message) {
      console.log("message was mutated with: ", message);
      state.message = message;
    }
  },
  actions: {
    setMessageAsync({ commit }, event) {
      setTimeout(() => {
        // NOTE: one or more commits possible
        commit("setMessage", event.target.value);
      }, 1000);
    }
  }
});

We have an action setMessageAsync that delays 1 sec (to simulate async behaviour) before committing the mutation setMessage.

creating a two way binding with a state item and an action

We bind a state item and an action to a component






 
 






 // src/App.vue
 
 <template> 
 
  <example-component-with-event-handler
    asr-bind-state="message"
    asr-bind-action="setMessageAsync AS setMessage"
  />

</template>
  
  ...

The component now has state item message and method setMessage available: (note that the component below is still the same component we used in the mutations example)





 



// src/components/ExampleMessageWithEventHandler.vue

<template>
    <p class="message">{{ message }}</p>
    <input v-bind:value="message" @keyup="setMessage">
  </div>
</template>

Notice we bind the message to the value attribute of of the input element and an event-handler setMessage that get's triggered at the keyup event.

And voila we have a nice two way binding at our hands implementing an action.

aliasing

Since we are also able to alias our actions we could easily reuse this component to create an instance with other store bindings:

Let's say we have:



 


 
 
 
 


 
 
 
 



export default new Vuex.Store({
  state: {
    anotherMessage: "another message in the root of the store"
  },
  mutations: {
    setAnotherMessage(state, message) {
      console.log("anotherMessage was mutated with: ", message);
      state.anotherMessage = message;
    }
  },
  actions: {
    setAnotherMessageAsync({ commit }, event) {
    setTimeout(() => {
      commit("setAnotherMessage", event.target.value);
    }, 1000);
  }
});

now we could bind the component like this (and reuse it):







 
 







 // src/App.vue
 
 <template> 
 
  <example-component-with-event-handler
    asr-bind-state="anotherMessage AS message"
    asr-bind-actions="setAnotherMessageAsync AS setMessage"
  />. 

  </template>
  
  ...

namespacing

As namespacing is a generic feature of vuex-asr could work like this:






 
 






 // src/App.vue
 
 <template> 
 
  <example-component-with-event-handler
    asr-bind-state="GENERAL/anotherMessage AS message"
    asr-bind-actions="GENERAL/setAnotherMessageAsync AS setMessage"
  />

  </template>
  
  ...

next steps

In the next chapters we go deeper into aliasing and namespacing and how these features could help us to improve the organisation of our front-end codebase.