Vuex is a state management pattern + library for Vue.js applications. It serves as a centralized store for all the components in an application, with rules ensuring that the state can only be mutated in a predictable fashion. Vuex is inspired by Flux, Redux, and The Elm Architecture, but it is designed specifically for Vue.js applications.
Key Concepts
- State: The single source of truth that holds the application’s data.
- Getters: Computed properties for the store’s state.
- Mutations: Synchronous functions that directly mutate the state.
- Actions: Asynchronous functions that commit mutations.
- Modules: Allow the store to be divided into smaller, manageable pieces.
Why Use Vuex?
- Centralized State Management: Vuex provides a single source of truth for the state, making it easier to manage and debug.
- Predictable State Mutations: By enforcing strict rules on how the state can be changed, Vuex ensures that the state transitions are predictable.
- Enhanced Debugging: Vuex integrates well with Vue Devtools, providing time-travel debugging and state snapshots.
Setting Up Vuex
To start using Vuex in your Vue.js application, follow these steps:
Step 1: Install Vuex
You can install Vuex via npm or yarn:
Step 2: Create a Vuex Store
Create a store.js
file in your project directory:
import { createStore } from 'vuex'; const store = createStore({ state() { return { count: 0 }; }, mutations: { increment(state) { state.count++; } }, actions: { increment(context) { context.commit('increment'); } }, getters: { doubleCount(state) { return state.count * 2; } } }); export default store;
Step 3: Integrate Vuex with Vue
In your main application file (e.g., main.js
), import and use the store:
import { createApp } from 'vue'; import App from './App.vue'; import store from './store'; const app = createApp(App); app.use(store); app.mount('#app');
Practical Example
Let's create a simple counter application to demonstrate the basic usage of Vuex.
Step 1: Define the Store
Create a store.js
file:
import { createStore } from 'vuex'; const store = createStore({ state() { return { count: 0 }; }, mutations: { increment(state) { state.count++; }, decrement(state) { state.count--; } }, actions: { increment(context) { context.commit('increment'); }, decrement(context) { context.commit('decrement'); } }, getters: { count(state) { return state.count; } } }); export default store;
Step 2: Create the Vue Component
Create a Counter.vue
component:
<template> <div> <p>Count: {{ count }}</p> <button @click="increment">Increment</button> <button @click="decrement">Decrement</button> </div> </template> <script> import { mapGetters, mapActions } from 'vuex'; export default { computed: { ...mapGetters(['count']) }, methods: { ...mapActions(['increment', 'decrement']) } }; </script>
Step 3: Integrate the Component
In your main application file (e.g., App.vue
):
<template> <div id="app"> <Counter /> </div> </template> <script> import Counter from './components/Counter.vue'; export default { components: { Counter } }; </script>
Exercises
Exercise 1: Add a Reset Button
Task: Add a button to the Counter.vue
component that resets the count to zero.
Solution:
- Update the Store:
mutations: { increment(state) { state.count++; }, decrement(state) { state.count--; }, reset(state) { state.count = 0; } }, actions: { increment(context) { context.commit('increment'); }, decrement(context) { context.commit('decrement'); }, reset(context) { context.commit('reset'); } }
- Update the Component:
<template> <div> <p>Count: {{ count }}</p> <button @click="increment">Increment</button> <button @click="decrement">Decrement</button> <button @click="reset">Reset</button> </div> </template> <script> import { mapGetters, mapActions } from 'vuex'; export default { computed: { ...mapGetters(['count']) }, methods: { ...mapActions(['increment', 'decrement', 'reset']) } }; </script>
Exercise 2: Add a Double Count Getter
Task: Add a getter to the store that returns the double of the current count.
Solution:
- Update the Store:
- Update the Component:
<template> <div> <p>Count: {{ count }}</p> <p>Double Count: {{ doubleCount }}</p> <button @click="increment">Increment</button> <button @click="decrement">Decrement</button> <button @click="reset">Reset</button> </div> </template> <script> import { mapGetters, mapActions } from 'vuex'; export default { computed: { ...mapGetters(['count', 'doubleCount']) }, methods: { ...mapActions(['increment', 'decrement', 'reset']) } }; </script>
Conclusion
In this section, we introduced Vuex and its core concepts: state, getters, mutations, actions, and modules. We also demonstrated how to set up Vuex in a Vue.js application and provided practical examples to illustrate its usage. By centralizing state management, Vuex helps maintain a predictable and manageable state in your Vue.js applications. In the next module, we will dive deeper into the state, getters, mutations, and actions to further enhance your understanding of Vuex.
Vue.js Course
Module 1: Introduction to Vue.js
- What is Vue.js?
- Setting Up the Development Environment
- Creating Your First Vue Application
- Understanding the Vue Instance
Module 2: Vue.js Basics
- Template Syntax
- Data Binding
- Computed Properties and Watchers
- Class and Style Bindings
- Conditional Rendering
- List Rendering
Module 3: Vue.js Components
- Introduction to Components
- Props and Custom Events
- Slots
- Dynamic and Async Components
- Component Communication
Module 4: Vue Router
Module 5: State Management with Vuex
- Introduction to Vuex
- State, Getters, Mutations, and Actions
- Modules in Vuex
- Using Vuex in Components
- Advanced Vuex Patterns
Module 6: Vue.js Directives
Module 7: Vue.js Plugins
Module 8: Testing in Vue.js
Module 9: Advanced Vue.js Concepts
- Render Functions and JSX
- Server-Side Rendering (SSR) with Nuxt.js
- Vue 3 Composition API
- Performance Optimization