Fetching data from external APIs and managing the state with Vuex are essential skills for building dynamic Vue.js applications. In this guide, we'll explore how to fetch data using Axios, store it in Vuex, and then display that data in a Vue component.
Why Use Vuex for State Management?
Vuex is the state management pattern and library for Vue.js applications. It serves as a centralized store for all the components, enabling a predictable way to manage shared data across the app.
Step 1: Setting Up Axios and Vuex
First, let's make sure we have both Axios and Vuex installed in our project:
npm install axios vuex
Step 2: Understanding JSONPlaceholder as a Data Source
Before diving into the implementation, let's discuss the data source we will be using in this example. We are using JSONPlaceholder, which is a free online REST API that provides fake data for testing and prototyping. JSONPlaceholder is commonly used by developers to practice fetching data without needing to set up a backend server.
In this tutorial, we'll specifically fetch user data from JSONPlaceholder's /users endpoint
This data serves as a great example because it closely resembles the kind of data you would retrieve from a real-world API, making it perfect for practicing how to handle API responses.
Here's an example of what the user data from JSONPlaceholder looks like:
[
{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"email": "Sincere@april.biz",
"address": {
"street": "Kulas Light",
"suite": "Apt. 556",
"city": "Gwenborough",
"zipcode": "92998-3874"
},
"phone": "1-770-736-8031 x56442",
"website": "hildegard.org",
"company": {
"name": "Romaguera-Crona",
"catchPhrase": "Multi-layered client-server neural-net",
"bs": "harness real-time e-markets"
}
}
]
This structure gives you a variety of data to work with, which is helpful when learning how to manipulate and display different data types in your Vue components.
Step 3: Setting Up the Vuex Store
We will create a Vuex store to manage the fetched data. Let's define the store with actions to fetch the data, mutations to update the state, and getters to retrieve the data.
Create a store.js
file with the following code:
import Vue from 'vue';
import Vuex from 'vuex';
import axios from 'axios';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
users: [],
loading: false,
},
mutations: {
SET_USERS(state, users) {
state.users = users;
},
SET_LOADING(state, isLoading) {
state.loading = isLoading;
},
},
actions: {
async fetchUsers({ commit }) {
commit('SET_LOADING', true);
try {
const response = await axios.get('https://jsonplaceholder.typicode.com/users');
commit('SET_USERS', response.data);
} catch (error) {
console.error('Failed to fetch users:', error);
} finally {
commit('SET_LOADING', false);
}
},
},
getters: {
allUsers: (state) => state.users,
isLoading: (state) => state.loading,
},
});
Explanation:
- state: Holds the application's data, including the users array and a loading state.
- mutations: Define how the state is updated. SET_USERS updates the user data, and SET_LOADING manages the loading state.
- actions: Perform asynchronous operations like data fetching. The fetchUsers action commits the SET_USERS mutation once data is successfully retrieved.
- getters: Provide a way to access the state data and loading status in a component.
Step 4: Using the Store in a Vue Component
Now, we'll connect our Vue component to the Vuex store to use the data fetched from the API. Here's an example of a component that triggers the data fetch and displays the list of users.
<template>
<div>
<h2>User List</h2>
<button @click="loadUsers" :disabled="loading">Load Users</button>
<p v-if="loading">Loading...</p>
<ul v-if="users.length && !loading">
<li v-for="user in users" :key="user.id">{{ user.name }}</li>
</ul>
<p v-else-if="!loading">No users available. Click the button to load users.</p>
</div>
</template>
<script>
import { mapGetters, mapActions } from 'vuex';
export default {
computed: {
...mapGetters(['allUsers', 'isLoading']),
},
methods: {
...mapActions(['fetchUsers']),
loadUsers() {
this.fetchUsers();
},
},
created() {
if (!this.allUsers.length) {
this.loadUsers();
}
},
};
</script>
Explanation:
- mapGetters: Allows easy access to Vuex getters in the component. We use allUsers to retrieve the data and isLoading to manage the loading state.
- mapActions: Maps Vuex actions to component methods. We use fetchUsers to trigger data fetching.
- loadUsers: This method calls the fetchUsers action to load users from the API when the button is clicked or when the component is created.
Step 5: Connecting the Store to the Vue Instance
Make sure to import and use the Vuex store in your main Vue instance:
import Vue from 'vue';
import App from './App.vue';
import store from './store';
Vue.config.productionTip = false;
new Vue({
store,
render: h => h(App),
}).$mount('#app');
By integrating Axios with Vuex, you can efficiently fetch and manage data in your Vue.js applications. Using JSONPlaceholder as a dummy data source allows you to practice these skills without setting up a backend server. This setup not only improves your code organization but also enhances the user experience by delivering data quickly and efficiently.
Top comments (4)
I think now I would use native fetch and pinia for that
I completely agree! Pinia is indeed a fantastic alternative to Vuex in Vue 3. Iām starting to migrate my projects to Pinia as well. Its simplicity and enhanced TypeScript support make it really appealing. Have you started using it in any of your projects?
Yes, I have. I like it, and I also prefer the composition API. One thing that can be hard to get is that there are no mutations in Pinia, so it has a different architecture than Vuex. I can recommend this as a starter https://www.youtube.com/watch?v=D61hGeliypY&t=488s
Thank you so much for the recommendation! I really appreciate it. Iām excited to dive deeper into Pinia and the Composition API. This video will definitely help me get started. Thanks š„