DEV Community

Cover image for πŸ”„ State Management with Vuex and Vue.js Lifecycle Hooks πŸš€
Dharmendra Kumar
Dharmendra Kumar

Posted on

πŸ”„ State Management with Vuex and Vue.js Lifecycle Hooks πŸš€

Managing global state in a Vue.js application is critical, especially when different components need to share data or react to changes. Vuex is the official state management library for Vue.js, offering a structured way to manage state globally. Combined with Vue.js Lifecycle Hooks, you can manage global state in a precise and predictable manner.

In this post, we will build a simple counter app using Vuex, showing how you can leverage Vue.js lifecycle hooks to interact with the state during different stages of the component's lifecycle.


🌍 What is Vuex?

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.


πŸ› οΈ Building a Simple Counter App with Vuex

Let’s walk through the steps to build a basic counter app where the state is managed globally using Vuex, and the component interacts with it via lifecycle hooks.


Step 1: Setting up the Vuex Store (store.js)

First, we need to create the Vuex store to manage our counter state globally. The store will include:

  • state: The initial value of the counter.
  • mutations: Functions that will modify the state.
  • actions: Methods that can dispatch mutations, which are useful for handling async operations (not needed in this case, but we’ll include it for clarity).
// store.js
import { createStore } from 'vuex';

export const store = createStore({
  state: {
    count: 0,  // The initial counter value
  },
  mutations: {
    increment(state) {
      state.count++;
    },
  },
  actions: {
    incrementCount({ commit }) {
      commit('increment');
    },
  },
});
Enter fullscreen mode Exit fullscreen mode
  • state: Holds the global counter value.
  • mutations: Vuex’s way of changing the state in a predictable manner.
  • actions: Useful for asynchronous operations but simply commits the increment mutation here.

Step 2: Using Vuex in the Vue Component

Next, we’ll create a Vue component that interacts with the Vuex store, utilizing lifecycle hooks to log and interact with the global state.

Counter Component (Counter.vue)
<template>
  <div>
    <h1>Global Counter: {{ count }}</h1>
    <button @click="incrementCount">Increment</button>
  </div>
</template>

<script>
import { mapState, mapActions } from 'vuex';

export default {
  computed: {
    // Using mapState to access global state
    ...mapState(['count']),
  },
  methods: {
    // Using mapActions to trigger actions
    ...mapActions(['incrementCount']),
  },
  created() {
    console.log('Component created! Current count is:', this.count);
  },
  updated() {
    console.log('Component updated! New count is:', this.count);
  },
};
</script>
Enter fullscreen mode Exit fullscreen mode
Explanation:
  1. mapState: Maps the global state count from the Vuex store to the component’s computed properties, allowing us to access count directly in the template.
  2. mapActions: Maps the incrementCount action, which commits the increment mutation to modify the state.
  3. Lifecycle Hooks:
    • created: Logs the initial counter value when the component is created.
    • updated: Logs the new counter value whenever the component re-renders due to state changes.

Step 3: Register the Vuex Store in Your App

Finally, we need to register the Vuex store in the main application file to make it available across all components.

main.js
import { createApp } from 'vue';
import App from './App.vue';
import { store } from './store';  // Import the Vuex store

const app = createApp(App);
app.use(store);  // Use Vuex in the app
app.mount('#app');
Enter fullscreen mode Exit fullscreen mode

🌟 Vue.js Lifecycle Hooks + Vuex: Practical Example

In this example, we utilize two lifecycle hooks (created and updated) to keep track of when the component is created and when it updates in response to state changes.

  1. created: This hook is called once the component is instantiated but before it’s mounted. It's a good place to fetch initial data or log the current state.
  2. updated: This hook is called every time the state is updated and the DOM is re-rendered. It helps in tracking changes to reactive data.

πŸ“ Full Example: Counter App with Vuex and Lifecycle Hooks

// Counter.vue
<template>
  <div>
    <h1>Global Counter: {{ count }}</h1>
    <button @click="incrementCount">Increment</button>
  </div>
</template>

<script>
import { mapState, mapActions } from 'vuex';

export default {
  computed: {
    // Maps the count from the Vuex store's state to this component's computed properties
    ...mapState(['count']),
  },
  methods: {
    // Maps the action to the component's methods
    ...mapActions(['incrementCount']),
  },
  created() {
    // Lifecycle hook: runs when the component is created
    console.log('Component created! Initial count:', this.count);
  },
  updated() {
    // Lifecycle hook: runs when the component is updated
    console.log('Component updated! New count:', this.count);
  },
};
</script>
Enter fullscreen mode Exit fullscreen mode

🧠 Key Takeaways

  • Vuex provides a centralized store to manage the global state of your application.
  • By using mapState and mapActions, you can easily access and modify global state inside your components.
  • Lifecycle hooks like created and updated give you more control over when and how you interact with your state.

With this approach, you have a structured and scalable way to manage global state using Vuex, while taking advantage of Vue.js lifecycle hooks for precise control over state initialization and updates!

Top comments (1)

Collapse
 
andrew-saeed profile image
Andrew Saeed

Very informative. Thanks so much! I would like to know if Pinia is better than Vuex? what do you think?