
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
- Introduction
- Installation
- State
- Getters
- Mutations
- Actions
- Modules
- Dynamic Module Registration
- Map Helper
- Namespaced Modules
- Asynchronous Actions
- Strict Mode
- Plugins
- Hot Module Replacement (HMR)
- Vuex Error Handling
- Testing
- 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) |
|
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 |