Vuex Legacy
Traditional state management for Vue 2 applications
📚 What is Vuex?
Vuex is the original state management pattern for Vue applications. It serves as a centralized store with strict rules for predictable state changes, primarily used in Vue 2 projects.
// Basic Vuex store
import { createStore } from 'vuex'
const store = createStore({
state: { count: 0 },
mutations: {
increment(state) {
state.count++
}
}
})
Core Vuex Concepts
State
Single source of truth
state: {
user: null,
items: []
}
Mutations
Synchronous state changes
mutations: {
SET_USER(state, user) {
state.user = user
}
}
Actions
Async operations
actions: {
async fetchUser({ commit }) {
const user = await api.get()
commit('SET_USER', user)
}
}
Getters
Computed store values
getters: {
isLoggedIn: state =>
!!state.user
}
🔹 Creating a Vuex Store
Set up a complete Vuex store with all core concepts:
// store/index.js
import { createStore } from 'vuex'
export default createStore({
state: {
todos: [],
filter: 'all'
},
getters: {
filteredTodos: (state) => {
if (state.filter === 'completed') {
return state.todos.filter(t => t.completed)
}
return state.todos
}
},
mutations: {
ADD_TODO(state, todo) {
state.todos.push(todo)
},
TOGGLE_TODO(state, id) {
const todo = state.todos.find(t => t.id === id)
if (todo) todo.completed = !todo.completed
}
},
actions: {
addTodo({ commit }, text) {
commit('ADD_TODO', {
id: Date.now(),
text,
completed: false
})
}
}
})
🔹 Using Vuex in Components
Access store state and dispatch actions in components:
<template>
<div>
<h2>Todo Count: {{ todoCount }}</h2>
<ul>
<li v-for="todo in filteredTodos" :key="todo.id">
{{ todo.text }}
</li>
</ul>
<button @click="addNewTodo">Add Todo</button>
</div>
</template>
<script>
import { mapState, mapGetters, mapActions } from 'vuex'
export default {
computed: {
...mapState(['todos']),
...mapGetters(['filteredTodos']),
todoCount() {
return this.$store.state.todos.length
}
},
methods: {
...mapActions(['addTodo']),
addNewTodo() {
this.addTodo('New task')
}
}
}
</script>
🔹 Modules for Organization
Split large stores into separate modules:
// store/modules/user.js
export default {
namespaced: true,
state: { profile: null },
mutations: {
SET_PROFILE(state, profile) {
state.profile = profile
}
},
actions: {
updateProfile({ commit }, profile) {
commit('SET_PROFILE', profile)
}
}
}
// store/index.js
import user from './modules/user'
export default createStore({
modules: {
user
}
})
// Usage in component
this.$store.dispatch('user/updateProfile', data)
🔹 Vuex vs Pinia
Understanding the differences:
Why Pinia is Recommended:
- Simpler API: No mutations, just actions
- TypeScript: Better type inference
- Modular: Each store is independent
- DevTools: Enhanced debugging experience
- Vue 3: Designed for Composition API
Note: Vuex is in maintenance mode. Use Pinia for new projects.
🔹 Installation & Setup
Set up Vuex in your Vue application:
// Install: npm install vuex@next
// main.js
import { createApp } from 'vue'
import store from './store'
import App from './App.vue'
const app = createApp(App)
app.use(store)
app.mount('#app')