Using Axios in Vue 3
Vue 3, as one of the most popular frontend frameworks today, has significantly improved development efficiency with its reactive system and Composition API. However, no matter how powerful a framework is, the core of handling asynchronous data interaction often cannot do without an HTTP request library. Axios has become the de facto preferred HTTP client in the Vue 3 ecosystem thanks to its native Promise support, interceptor mechanism, and cross-domain handling capabilities. This article will guide you in detail on how to integrate Axios into a Vue 3 project and demonstrate how to seamlessly incorporate it into the development pattern of the Composition API.
Installation and Basic Configuration
Before writing code, you need to ensure that Axios is installed in your project environment. For Vue 3 projects built with Vite or Webpack, installation can be done via npm or yarn:
npm install axios
# Or
yarn add axios
After installation, Axios will automatically register as a global object axios, which does not require explicit importing in the code. However, in large projects, to avoid naming conflicts and facilitate instance configuration management, it is recommended to create an independent configuration file (e.g., src/axios.js) to centrally manage Axios instances.
Encapsulating Axios Instances and Interceptors
The component-based characteristics of Vue 3 mean that each component may initiate network requests, and repetitive configuration code can severely impact maintainability. By encapsulating an Axios instance with interceptors, we can uniformly handle request and response logic, including loading states, error messages, token injection, and other common scenarios.
The core configuration in src/axios.js is defined as follows:
import axios from 'axios'
// Create a custom instance
const service = axios.create({
baseURL: '/api', // Request base path
timeout: 5000, // Timeout (milliseconds)
})
// Request interceptor: Uniformly handle token injection and loading state
service.interceptors.request.use(
(config) => {
const token = localStorage.getItem('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
},
(error) => {
// Handle request errors
return Promise.reject(error)
}
)
// Response interceptor: Uniformly handle response status and error messages
service.interceptors.response.use(
(response) => {
const res = response.data
if (res.code !== 200) {
// Non-success status code, throw an error object for uniform capture
return Promise.reject(new Error(res.message || 'Error'))
} else {
return res
}
},
(error) => {
console.log('Axios Error:', error)
// Display friendly提示信息 based on error type
return Promise.reject(error.message)
}
)
export default service
With the above configuration, all initiated requests will automatically carry the Token, and responses with non-200 statuses will be converted into standard error objects, making it easy to handle them uniformly in components.
Request Practices in Composition API
The core advantage of Vue 3 lies in its Composition API, which allows us to organize logic modularly by function. In actual development, we usually initiate requests using useFetch or directly within the <script setup> tag using the onMounted lifecycle hook.
Here is a typical component example for retrieving a user list:
<template>
<div class="user-list">
<div v-if="loading" class="loading">Loading...</div>
<ul v-else-if="error" class="error">{{ error }}</ul>
<ul v-else>
<li v-for="user in users" :key="user.id">
{{ user.name }} - {{ user.email }}
</li>
</ul>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import request from './axios'
const loading = ref(false)
const error = ref(null)
const users = ref([])
// Simulate data fetching function
const fetchData = async () => {
loading.value = true
error.value = null
try {
const res = await request.get('/users')
users.value = res.data.list // Assuming the backend response structure includes a 'list' field
} catch (err) {
error.value = err.message
} finally {
loading.value = false
}
}
onMounted(() => {
fetchData()
})
</script>
In this example, we use ref to manage the loading state and error information, capturing exceptions thrown by Axios via a try...catch block. Since the interceptors have already uniformly handled non-200 status responses, we only need to focus on business logic here.
Concurrent Requests and Cancellation Strategies
In practical applications, users may initiate multiple requests simultaneously (e.g., fetching detail lists and user information during a search). Axios provides the all method for initiating multiple requests in parallel and supports canceling incomplete requests via the instance's cancelToken, which is crucial for preventing "phantom requests".
// Import CancelToken in axios.js
import axios from 'axios'
import { CancelToken } from 'axios'
const service = axios.create({ ... })
const cancelTokenSource = axios.CancelToken.source()
service.interceptors.request.use((config) => {
config.cancelToken = cancelTokenSource.token // Inject cancellation token
})
// Example of canceling requests in a component
onMounted(() => {
fetchData()
})
function onUnmounted() {
cancelTokenSource.cancel('Component unmounted')
}
In this way, when a Vue 3 component is unmounted, any incomplete network requests will be automatically canceled, avoiding memory leaks and invalid data updates.
Summary
The perfect combination of Axios and Vue 3 not only simplifies the process of acquiring asynchronous data but also enhances code robustness and maintainability through the interceptor mechanism. Whether it's simple GET/POST requests or complex concurrent data stream processing, developers can build efficient, stable, and easily extensible frontend applications under the Composition API framework of Vue 3 with Axios's Promise support and flexible configuration capabilities. Mastering these techniques is an essential step for every Vue 3 developer to reach a professional level.