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

  1. State: The single source of truth that holds the application’s data.
  2. Getters: Computed properties for the store’s state.
  3. Mutations: Synchronous functions that directly mutate the state.
  4. Actions: Asynchronous functions that commit mutations.
  5. 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:

npm install vuex@next --save
# or
yarn add vuex@next

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:

  1. 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');
  }
}
  1. 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:

  1. Update the Store:
getters: {
  count(state) {
    return state.count;
  },
  doubleCount(state) {
    return state.count * 2;
  }
}
  1. 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.

© Copyright 2024. All rights reserved