A Deep Dive Into VUEX 4
Tags: webdev, vue, vscode
Published: 2024-04-26 09:18:58

**Introduction**
Vuex is a state-management technique and library for Vue.js applications. It acts as a centralized repository for all of the components of an application in other words, think of Vuex as a kitchen organizer. It's like a magic pantry that keeps all of your ingredients in one spot, perfectly arranged, and easily accessible. But it's not just any pantry it's a smart pantry that follows certain principles. With Vuex, all of your Vue.js application's components, such as buttons, forms, and menus, may communicate with one another over this pantry. They can discuss and update information without becoming confused or causing a mess. It's similar to having a clear set of guidelines for how things should be done in the kitchen. Vuex keeps everything in order, ensuring that your Vue.js apps function smoothly and efficiently.

**What is State Management?**
State management is similar to having a master filing cabinet for all of the critical information in your application. Instead of scattered notes and documents, everything is carefully arranged in one central spot known as the "State".

This configuration has numerous advantages, the most notable of which is that it keeps your app clean and simple to maintain. You won't have to play detective to figure out where a piece of data comes from because it's all saved in one location. This saves you the hassle of transferring data back and forth between different portions of your software, which can soon become a tangled mess of misunderstanding.

State management is very important if you want to construct scalable apps. It's a structured and maintainable pattern based on a single source of truth, making it suitable for both large and small applications with room for expansion.


**Why Vuex?**
Vuex advocates breaking down views into components, which are reusable Vue objects that can accept data and operations. The data within these components represents the view's state, and methods let us change that state based on user interactions.

For example, when a user clicks a button in a component, a corresponding method is called. This method then takes action on the component's state, causing it to change. As a result, the view now reflects the modifications made to the state. This seamless interaction of methods and data provides a dynamic and responsive user experience.

As your project increases in complexity, you may find yourself providing props across components and manually manipulating the DOM to access other components. However, this strategy can quickly become tiresome, resulting in a codebase that is difficult to maintain or debug, particularly when problems occur.

This is when Vuex comes in useful. It provides a centralized store where you may store all states that need to be shared by several components. Rather than sending props around and altering the DOM directly, Vuex offers a global scope for managing the application state. This makes it easy to manage, update, and retrieve data throughout your Vue.js application, resulting in a more maintainable and scalable code base.

**When to Use a Vuex Store**
There are various cases in which employing a Vuex data store makes complete sense.  Here's how to decide when to use it:

- **When props become unmaintainable:** There is no set number of props indicating when to transition to Vuex. Instead, it is about getting to a point where controlling the component becomes difficult. If you've previously worked with components, you may have encountered instances in which data management appears to be simpler. That's when you should consider using Vuex.

- **Building massively complex forms:** This is an area where Vuex really excels. Initially, I assumed it was mostly for maintaining state in single-page applications (which it does incredibly well). However, when working with forms that dynamically update data depending on user inputs, things can rapidly become complex across your components. That's when using Vuex can make a significant difference.

- **Sharing data across an entire SPA:** This situation excellently explains when and how to use Vuex. Vuex is primarily intended to share data across an entire single-page application. Vuex allows for the effective management of global application data such as user information, notifications, and more. With Vuex's state management mechanism, exposing any piece of data throughout the entire application is simple and efficient

- **Creating a page with multiple moving parts:** Sometimes you come across pages that are quite complex. Complex pages can be compared to small, stand-alone programs. Using the Vuex store will allow you to easily share data with other VueJs components, this method can be used in other apps as well, building a store that is especially tuned to the needs of a certain page.


**Installing Vuex 4**
To install Vuex 4, just run the following command:

```
npm install vuex --save
```

After installing Vuex into your project, you'll need to initialize it by creating a store.js file and adding the following code:

```
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
```

Let us now proceed to establish the store. The store effectively functions as a reactive object that maintains the application's state, along with getters, mutations, and actions.

**Understanding the store**
The store is essentially the centralized state, with some fundamental principles that enable us to achieve this centralization. These ideas include:

- State

- Getters

- Mutations

- Actions

**State**
This is a single object that stores all of the application's data. It acts similarly to the 'data' keyword in the structure of single components, with the important distinction that this state can be accessed from numerous components. When this state is modified, any components that access it are automatically updated. To create this object, we do the following.

```
// import Vue
import Vue from 'vue';
// import Vuex
import Vuex from 'vuex';
// Install the Vuex plugin on vue
Vue.use(Vuex);
// create a Vuex store instance
export const store = new Vuex.Store({
   state: {
       cart: ''
   }
})
```

**Getters**
In Vuex, getters function similarly to stored computed properties. They allow us to create a new state depending on the present one, such as determining the total number of products in a shopping cart.

Getters also assist in eliminating code duplication. Instead of executing the same data processing in different components, we may declare it once in a getter and use it throughout our application.

To build a getter, we perform the following:

```
// import Vue
import Vue from 'vue';
// import Vuex
import Vuex from 'vuex';
// Install the Vuex plugin on vue
Vue.use(Vuex);
// create a Vuex store instance
export const store = new Vuex.Store({
   state: {
       cart: ["bread", "rice", "beans", "turkey"]
   },

   getters: {
       // Fetch the total number of items in the cart
       totalNumberOfCartItems: state => {
           return state.cart.length;
       },
   },
})

```


**Mutations** 
Vuex's state can only be updated through mutations. They have one responsibility to establish a state. A mutation is a function that takes two arguments: the state and the payload, which is optional.

The payload contains the data necessary to update the state. Mutations are synchronous, thus we can't conduct asynchronous actions within them.

Now, let us add a mutation to our code.

```
// import Vue
import Vue from 'vue';
// import Vuex
import Vuex from 'vuex';
// Install the Vuex plugin on vue
Vue.use(Vuex);
// create a Vuex store instance
export const store = new Vuex.Store({
   state: {
       cart: ["bread", "rice", "beans", "turkey"]
   },

   getters: {
       // Fetch the total number of items in the cart
       totalNumberOfCartItems: state => {
           return state.cart.length;
       },
   },
  
   mutations: {
       // Add item to cart
       addItemToCart (state, payload) {
           state.cart.push(payload);
       },
   },
})
```


**Actions**
Actions in Vuex are similar to mutations, but instead of directly affecting the state, they cause mutations. They are asynchronous, which allows us to do time-consuming tasks like making HTTP queries to APIs. Once these activities are performed, we can commit a mutation to update the state appropriately.

For example, suppose we wish to send the goods in a shopping cart to an API. This action would involve sending an asynchronous request to the API. Once the call is completed and we receive a response, we can then commit a mutation to update the cart's state based on the API answer.

```
// import Vue
import Vue from 'vue';
// import Vuex
import Vuex from 'vuex';
// Install the Vuex plugin on vue
Vue.use(Vuex);
// create a Vuex store instance
export const store = new Vuex.Store({
   state: {
       cart: ["bread", "rice", "beans", "turkey"]
   },

   getters: {
       // Fetch the total number of items in the cart
       totalNumberOfCartItems: state => {
           return state.cart.length;
       },
   },
  
   mutations: {
       // Add item to cart
       addItemToCart (state, payload) {
           state.cart.push(payload);
       },
       // Clear items in the cart
       emtpyCart (state) {
           state.cart = [];
       }
   },
  
   actions: {
       checkout({commit}, requestObject) {
           // API Call to submit the items in the cart
           Vue.http.post('submit', requestObject).then((response) => {
               // log success
               console.log(response);
               // Clear Cart by mutating the state
               commit('emptyCart');
           }).catch((error) => {
               // log error
               console.log(error);
           }
       }
   }
})
```

Looking at the code above, we defined an activity called checkout that accepts two things:

- commit: this allows us to trigger the commit method within our actions.

- requestObject: this allows us to pass data into an action.


**Conclusion** 
Going into Vuex 4, you'll realize it's like having a well-organized toolkit for controlling all aspects of your web app. It keeps everything organized, so you can find what you need when you need it. Furthermore, it improves communication between different components of your program, resulting in a smoother and more effective development process overall.