Vuex Cheatsheet



This Vuex Cheatsheet provides a quick reference to key features such as state management, getters, mutations, actions, modules, and more with practical code examples for each concept. It helps developers manage complex Vue.js application state efficiently.

Table of Contents

  1. Introduction
  2. Installation
  3. State
  4. Getters
  5. Mutations
  6. Actions
  7. Modules
  8. Dynamic Module Registration
  9. Map Helper
  10. Namespaced Modules
  11. Asynchronous Actions
  12. Strict Mode
  13. Plugins
  14. Hot Module Replacement (HMR)
  15. Vuex Error Handling
  16. Testing
  17. Migration from 3.x to 4.0

Introduction

Vuex is a state management for Vue.js applications which by centralizing components state, allows state management of the whole application. It works perfectly well with Vues reactivity system and also supports such phenomena as actions, mutations, and getters, necessary for organizing and further modification of the state of the application.

Installation

Import Vuex and create a store instance to manage the state of your application. This section shows how to set up Vuex in a Vue 3 project.

Import Vuex and Create Store:

import { createApp } from 'vue';
import { createStore } from 'vuex';

Create Store Instance:

const store = createStore({
  state() {
    return {
      count: 0 // Initial state
    };
  },
  mutations: {
    increment(state) {
      state.count++; // Mutate the state
    }
  }
});

Install Store in Vue Application:

const app = createApp({ /* Root Component */ });
app.use(store);

Access State and Mutations

Directly in JavaScript:

store.commit('increment'); // Commit a mutation
console.log(store.state.count); // Access the updated state

Access State:

computed: {
count() {
return this.$store.state.count;
},
},

Commit a Mutation:

methods: {
increment() {
this.$store.commit('increment');
console.log(this.$store.state.count);
},
},

State

State in Vuex holds the central data for your application. It can be accessed in components via computed properties or directly from the store.

Example: Access state in a component:

computed: {
  count() {
    return this.$store.state.counter.count;
  }
}

Accessing state outside a component:

import store from '../store';
console.log(store.state.counter.count);

Getters

Getters compute derived state based on store state and can be accessed globally or within modules. They work like computed properties for the store.

Accessing getters globally:

console.log(store.getters.totalItems);

Method style getter example:

getters: {
  getItemById: (state) => (id) => {
    return state.items.find(item => item.id === id);
  }
}
console.log(store.getters.getItemById(2));

Accessing a module getter:

console.log(store.getters['cart/totalPrice']);

Mutations

Mutations are the only way to directly modify state in Vuex. They receive the current state and a payload as arguments.

Arguments for Mutation Functions:

  • state: The local state.
  • payload: Optional data passed when committing a mutation.

Example of defining a mutation:

mutations: {
  addItem(state, newItem) {
    state.items.push(newItem);
  }
}

Committing a mutation from a component:

this.$store.commit('cart/addItem', { id: 1, name: 'Book' });

Actions

Actions handle asynchronous operations and commit mutations when data is ready.

Arguments for Action Functions:

  • context: Includes state, commit, dispatch, getters, etc.
  • payload: Optional data passed when dispatching an action.

Example of an action that fetches items:

actions: {
  fetchItems({ commit }) {
    return api.getItems().then(items => {
      commit('setItems', items);
    });
  }
}

Dispatching an action from a component:

this.$store.dispatch('cart/fetchItems');

Modules

Modules allow you to split your Vuex store into smaller, manageable pieces with their own state, mutations, actions, and getters.

Example module definition:

const cartModule = {
  state: {
    items: []
  },
  getters: {
    itemCount(state) {
      return state.items.length;
    }
  },
  mutations: {
    addItem(state, item) {
      state.items.push(item);
    }
  },
  actions: {
    loadItems({ commit }) {
      api.fetchCartItems().then(items => {
        commit('setItems', items);
      });
    }
  }
};

const store = new Vuex.Store({
  modules: {
    cart: cartModule
  }
});

Accessing module state:

console.log(store.state.cart.items);

Dynamic Module Registration

You can register Vuex modules dynamically after the store has been created. This is useful for code splitting and on-demand module loading.

Registering a simple module:

store.registerModule('myModule', {
  // module definition
});

Registering a nested module:

store.registerModule(['nested', 'myModule'], {
  // module definition
});

Map Helper

Vuex provides map helpers to bind state, getters, mutations, and actions to component computed properties and methods.

mapState

Use mapState to map Vuex state properties to computed properties in a Vue component.

Import the Helper:

import { mapState } from 'vuex';
    

Map Specific State Properties:

computed: mapState({
  count: state => state.count, // Custom name
  countAlias: 'count' // Use the same name as in the state
})
    

Map State Properties Using an Array:

computed: mapState(['count', 'total'])
    

Combine with Local Computed Properties:

computed: {
  localProperty() {
    return this.localValue * 2;
  },
  ...mapState(['count'])
}
    

mapGetters

Use mapGetters to map Vuex getters to computed properties.

Import the Helper:

import { mapGetters } from 'vuex';
    

Map Specific Getters:

computed: mapGetters({
  doubledCount: 'doubledCount' // Map getter to a custom name
})
    

Map Getters Using an Array:

computed: mapGetters(['doubledCount', 'isLoggedIn'])
    

mapMutations

Use mapMutations to map Vuex mutations to component methods.

Import the Helper:

import { mapMutations } from 'vuex';
    

Map Specific Mutations:

methods: mapMutations({
  increment: 'increment' // Map mutation to a custom name
})
    

Map Mutations Using an Array:

methods: mapMutations(['increment', 'decrement'])
    

Combine with Local Methods:

methods: {
  ...mapMutations(['increment']),
  localMethod() {
    console.log('This is a local method.');
  }
}
    

mapActions

Use mapActions to map Vuex actions to component methods.

Import the Helper:

import { mapActions } from 'vuex';
    

Map Specific Actions:

methods: mapActions({
  fetchUser: 'fetchUser' // Map action to a custom name
})
    

Map Actions Using an Array:

methods: mapActions(['fetchUser', 'logout'])
    

Combine with Local Methods:

methods: {
  ...mapActions(['fetchUser']),
  anotherMethod() {
    console.log('This is another local method.');
  }
}
    

Vuex Helper Comparison Table

Helper Functionality Example Usage
mapState Maps Vuex state to computed properties computed: mapState(['count'])
mapGetters Maps Vuex getters to computed properties computed: mapGetters(['doubledCount'])
mapMutations Maps Vuex mutations to methods methods: mapMutations(['increment'])
mapActions Maps Vuex actions to methods methods: mapActions(['fetchUser'])

Namespaced Modules

Namespaced modules allow you to encapsulate Vuex modules and avoid naming collisions. Use the namespace prefix when accessing state, mutations, actions, and getters.

Feature Description Code Example
Enable Namespacing Add namespaced: true to the module definition.
const moduleA = {
  namespaced: true,
  state: { count: 0 },
  mutations: {
    increment(state) {
      state.count++;
    }
  }
};
        
Access in Components Use the namespace prefix in helpers or via this.$store.
computed: {
  ...mapState('moduleA', ['count'])
},
methods: {
  ...mapMutations('moduleA', ['increment'])
}
        
Dispatch an Action Include the namespace when dispatching.
this.$store.dispatch('moduleA/actionName');
        
Commit a Mutation Include the namespace when committing.
this.$store.commit('moduleA/mutationName');
        
Combine Helpers Specify namespace with helpers like mapState.
computed: {
  ...mapState('moduleA', { localCount: 'count' })
}
        
Module Registration Register namespaced modules in the store.
const store = createStore({
  modules: { moduleA }
});
        

Asynchronous Actions

Actions can perform asynchronous operations such as API calls and commit mutations when resolved. They support Promises and async/await syntax.

Feature Description Code Example
Define an Action Actions return Promises (async/await supported).
actions: { 
  async fetchData({ commit }) { 
    const data = await fetch('/api/data').then(res => res.json()); 
    commit('setData', data); 
  } 
}
                
Dispatch an Action Trigger an action with dispatch.
this.$store.dispatch('fetchData');
                
Access in Namespaced Module Prefix with the namespace.
this.$store.dispatch('moduleA/fetchData');
                
Use with Payload Pass data when dispatching.
actions: { 
  async saveData({ commit }, payload) { 
    const res = await api.save(payload); 
    commit('updateState', res); 
  } 
}
                
Async/Await in Component Wait for the action to complete.
async fetchData() { 
  await this.$store.dispatch('fetchData'); 
  console.log('Data fetched!'); 
}
                
Combine with mapActions Use the helper to simplify action mapping.
methods: {
  ...mapActions(['fetchData', 'saveData']),
}
                

Strict Mode

Strict mode ensures that Vuex state is only mutated through mutations. This helps catch accidental state changes.

Example of enabling strict mode:

const store = createStore({
  state: { count: 0 },
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  strict: true // Enable strict mode for development
});

When strict mode is active, direct state mutations will cause an error:

store.state.count = 5; // Error: Do not mutate Vuex store state outside mutation handlers

Plugins

Plugins extend Vuex functionality by hooking into the stores lifecycle. They can be used for logging, state persistence, or custom behavior.

Feature Description Example
What is a Plugin? Hooks into the stores mutation lifecycle.
const myPlugin = (store) => {
  store.subscribe((mutation, state) => {
    // Plugin code here
  });
};
        
How to Add a Plugin Add the plugin to the store's plugins array.
const store = createStore({
  plugins: [myPlugin]
});
        
Mutating State Use store.commit for state changes.
store.commit('mutationName', payload);
        
State Snapshot Compare pre- and post-mutation states.
let prevState = _.cloneDeep(store.state);
store.subscribe((mutation, state) => {
  // Compare states here
});
        
Environment-Specific Plugins Enable plugins only in development.
plugins: process.env.NODE_ENV !== 'production' ? [myPlugin] : []
        
Syncing with Data Sources Synchronize external data with the store.
socket.on('data', data => {
  store.commit('receiveData', data);
});
        
Built-in Logger Plugin Logs mutations and actions for debugging.
import { createLogger } from 'vuex';
const store = createStore({
  plugins: [createLogger()]
});
        
Logger Options Customize logging behavior.
const logger = createLogger({ collapsed: true });
        

Hot Module Replacement (HMR)

HMR enables live updating of Vuex modules without a full page reload. This improves development efficiency by preserving the state during updates.

Task Code Example
Enable HMR for Mutations/Modules
if (module.hot) {
  module.hot.accept(['./mutations', './modules/a'], () => {
    const newMutations = require('./mutations').default;
    const newModuleA = require('./modules/a').default;
    store.hotUpdate({
      mutations: newMutations,
      modules: { a: newModuleA }
    });
  });
}
        
Dynamic Module Loading
function loadModules() {
  const context = require.context('./modules', false, /([a-z_]+)\\.js$/i);
  return context.keys().reduce((modules, key) => {
    const name = key.match(/([a-z_]+)\\.js$/i)[1];
    return { ...modules, [name]: context(key).default };
  }, {});
}

if (module.hot) {
  module.hot.accept(context.id, () => {
    const { modules } = loadModules();
    store.hotUpdate({ modules });
  });
}
        

Vuex Error Handling

Error handling in Vuex helps track and display errors that occur within the store. Use mutations and actions to manage error state.

Task Code Example Description
Store Error in State
export default new Vuex.Store({
  state: { error: "" }
});
        
Initialize an error property in the Vuex store.
Display Error (Vue Component)
{{ this.$store.state.error }}
Render error messages in a component.
Dismiss Error
this.$store.state.error = "";
        
Clear the error message.
Set Error in Component
this.$store.state.error = "Your error message here";
        
Directly assign an error message (not recommended outside mutations).
Using Mutations
mutations: {
  POST_ERROR: (state, payload) => { state.error = payload; }
}
        
Define a mutation to set error state.
Using Actions
actions: {
  SET_ERROR: (context, errorMsg) => {
    context.commit("POST_ERROR", errorMsg);
  }
}
        
Dispatch an action to update the error state via mutation.
Set Error in Module Action
context.rootState.error = "Error message";
        
Set error state from within a module action.

TypeScript Support Cheatsheet

The typescript support in Vuex is provided by the store and its defined in the table.

Task Code
Typing $store in Vue Component
declare module 'vue' { 
  interface State { count: number } 
  interface ComponentCustomProperties { 
    $store: Store<State> 
  } 
}
                
Define Typed Store
export interface State { 
  count: number 
} 

export const store = createStore<State>({ 
  state: { count: 0 } 
})
                
Using InjectionKey for Store
export const key: InjectionKey<Store<State>> = Symbol()
                
Install Typed Store in Vue
app.use(store, key)
                
Retrieve Typed Store in Component
import { useStore } from 'vuex' 

const store = useStore(key) 
store.state.count // typed as number
                
Simplified useStore Composable
export function useStore() { 
  return baseUseStore(key) 
}
                

Testing

Testing Vuex involves verifying mutations, actions, and getters. Use isolated tests to ensure your store logic works correctly.

Mutations Testing:

const mutations = {
  increment: state => state.count++
};

Actions Testing:

const actions = {
  getAllProducts: ({ commit }) => {
    commit('REQUEST_PRODUCTS');
    shop.getProducts(products => commit('RECEIVE_PRODUCTS', products));
  }
};

Getters Testing:

const getters = {
  filteredProducts: (state, { filterCategory }) =>
    state.products.filter(p => p.category === filterCategory)
};

Migration from 3.x to 4.0

This section highlights key differences between Vuex 3.x and Vuex 4.0, including installation, store creation, and TypeScript support. The migration aligns Vuex with Vue 3s composition API and modern bundling formats.

Feature Vuex 3.x Vuex 4.0
Installation import Vuex from 'vuex' import { createStore } from 'vuex'
Store Creation new Vuex.Store() createStore()
App Installation Vue.use(Vuex) app.use(store)
TypeScript Support Global typings for $store Must declare module augmentation for $store
Bundles - Bundles aligned with Vue 3: .esm-browser.js, .esm-bundler.js, .cjs.js
createLogger Function import { createLogger } from 'vuex/dist/logger' import { createLogger } from 'vuex'
useStore Composition Function - New useStore() function for the Composition API
Advertisements