Vue 3 是一个非常流行的前端框架,而 Axios 是一个基于 Promise 的 HTTP 客户端,经常用于与服务器进行交互。结合这两个工具,可以创建强大且灵活的前端应用。本博客将详细介绍如何在 Vue 3 中使用 Axios,包括基本用法、处理不同的请求类型、错误处理、拦截器、自定义实例以及在 Vue 组件中的实际应用等。为了更加贴近实际项目,本博客将重点使用 Vue 3 的 setup
语法糖。
1. 安装和基础配置
安装 Axios
首先,我们需要安装 Axios。可以通过 npm 或 yarn 进行安装:
npm install axios
# 或者
yarn add axios
基本配置
在 Vue 3 项目中,我们通常会在 src
目录下创建一个单独的文件来配置 Axios。例如,可以创建一个 src/utils/axios.js
文件:
// src/utils/axios.js
import axios from 'axios';
const instance = axios.create({
baseURL: 'https://', // 替换为实际的 API URL
timeout: 10000,
});
// 请求拦截器
instance.interceptors.request.use(
config => {
// 在请求发送之前做一些处理,比如添加授权头
config.headers.Authorization = `Bearer ${localStorage.getItem('token')}`;
return config;
},
error => {
// 处理请求错误
return Promise.reject(error);
}
);
// 响应拦截器
instance.interceptors.response.use(
response => {
// 对响应数据做一些处理
return response;
},
error => {
// 处理响应错误
if (error.response && error.response.status === 401) {
// 例如,处理未授权错误
console.error('Unauthorized, redirecting to login...');
// 可以添加重定向到登录页的逻辑
}
return Promise.reject(error);
}
);
export default instance;
2. 在 Vue 组件中使用 Axios
发起 GET 请求
在 Vue 组件中使用 Axios 非常简单。我们可以在 setup
函数中发起请求:
<template>
<div>
<h1>Users</h1>
<ul>
<li v-for="user in users" :key="user.id">{{ }}</li>
</ul>
</div>
</template>
<script>
import { ref, onMounted } from 'vue';
import axios from '../utils/axios';
export default {
setup() {
const users = ref([]);
const fetchUsers = async () => {
try {
const response = await axios.get('/users');
users.value = response.data;
} catch (error) {
console.error(error);
}
};
onMounted(fetchUsers);
return {
users
};
}
};
</script>
发起 POST 请求
<template>
<div>
<h1>Add User</h1>
<form @submit.prevent="addUser">
<input v-model="" placeholder="Name" />
<button type="submit">Add</button>
</form>
</div>
</template>
<script>
import { ref } from 'vue';
import axios from '../utils/axios';
export default {
setup() {
const newUser = ref({ name: '' });
const addUser = async () => {
try {
const response = await axios.post('/users', newUser.value);
console.log('User added:', response.data);
} catch (error) {
console.error(error);
}
};
return {
newUser,
addUser
};
}
};
</script>
3. 错误处理
处理错误是使用 Axios 时的重要部分。我们可以在 catch
块中处理错误,并根据需要显示错误消息:
import { ref } from 'vue';
import axios from '../utils/axios';
export default {
setup() {
const users = ref([]);
const errorMessage = ref('');
const fetchUsers = async () => {
try {
const response = await axios.get('/users');
users.value = response.data;
} catch (error) {
if (error.response) {
// 请求已发出,服务器响应状态码不在2xx范围内
errorMessage.value = `Error: ${error.response.data.message}`;
} else if (error.request) {
// 请求已发出,但没有收到响应
errorMessage.value = 'Error: No response from server';
} else {
// 设置请求时发生错误
errorMessage.value = `Error: ${error.message}`;
}
}
};
onMounted(fetchUsers);
return {
users,
errorMessage
};
}
};
4. 使用拦截器
拦截器允许我们在请求或响应被处理之前对其进行修改。常见的用例包括添加授权头或处理全局错误。
请求拦截器
请求拦截器已经在 src/utils/axios.js
中配置,如下:
instance.interceptors.request.use(
config => {
// 在请求发送之前做一些处理,比如添加授权头
config.headers.Authorization = `Bearer ${localStorage.getItem('token')}`;
return config;
},
error => {
// 处理请求错误
return Promise.reject(error);
}
);
响应拦截器
响应拦截器也已经在 src/utils/axios.js
中配置,如下:
instance.interceptors.response.use(
response => {
// 对响应数据做一些处理
return response;
},
error => {
// 处理响应错误
if (error.response && error.response.status === 401) {
// 例如,处理未授权错误
console.error('Unauthorized, redirecting to login...');
// 可以添加重定向到登录页的逻辑
}
return Promise.reject(error);
}
);
5. 创建和使用自定义 Axios 实例
在某些情况下,您可能需要为不同的 API 创建多个 Axios 实例。可以轻松创建自定义实例并在组件中使用它们:
// src/utils/githubAxios.js
import axios from 'axios';
const githubAxios = axios.create({
baseURL: 'https://',
timeout: 10000,
});
export default githubAxios;
在组件中使用自定义实例:
<template>
<div>
<h1>GitHub Repos</h1>
<ul>
<li v-for="repo in repos" :key="repo.id">{{ }}</li>
</ul>
</div>
</template>
<script>
import { ref, onMounted } from 'vue';
import githubAxios from '../utils/githubAxios';
export default {
setup() {
const repos = ref([]);
const fetchRepos = async () => {
try {
const response = await githubAxios.get('/users/your-username/repos');
repos.value = response.data;
} catch (error) {
console.error(error);
}
};
onMounted(fetchRepos);
return {
repos
};
}
};
</script>
6. 使用组合式 API
Vue 3 引入了组合式 API,可以更灵活地组织组件逻辑。以下是如何在组合式 API 中使用 Axios 的示例:
<template>
<div>
<h1>Posts</h1>
<ul>
<li v-for="post in posts" :key="post.id">{{ post.title }}</li>
</ul>
</div>
</template>
<script>
import { ref, onMounted } from 'vue';
import axios from '../utils/axios';
export default {
setup() {
const posts = ref([]);
const fetchPosts = async () => {
try {
const response = await axios.get('/posts');
posts.value = response.data;
} catch (error) {
console.error(error);
}
};
onMounted(fetchPosts);
return {
posts
};
}
};
</script>
7. 取消请求
在某些情况下,您可能需要取消正在进行的请求,例如用户导航到其他页面时。Axios 提供了取消令牌来实现这一点:
import axios from 'axios';
const CancelToken = axios.CancelToken;
let cancel;
axios.get('/longRequest', {
cancelToken: new CancelToken(function executor(c) {
cancel = c;
})
}).catch(function (thrown) {
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
} else {
// 处理错误
}
});
// 取消请求
cancel('Operation canceled by the user.');
在 Vue 组件中使用取消令牌:
<template>
<div>
<h1>Cancelable Request</h1>
<button @click="cancelRequest">Cancel Request</button>
</div>
</template>
<script>
import { ref, onBeforeUnmount } from 'vue';
import axios from '../utils/axios';
export default {
setup() {
const cancelTokenSource = ref(null);
const fetch
Data = async () => {
cancelTokenSource.value = axios.CancelToken.source();
try {
const response = await axios.get('/data', {
cancelToken: cancelTokenSource.value.token
});
// 处理响应
} catch (error) {
if (axios.isCancel(error)) {
console.log('Request canceled:', error.message);
} else {
console.error(error);
}
}
};
const cancelRequest = () => {
if (cancelTokenSource.value) {
cancelTokenSource.value.cancel('Operation canceled by the user.');
}
};
onBeforeUnmount(() => {
cancelRequest();
});
fetchData();
return {
cancelRequest
};
}
};
</script>
8. 上传和下载文件
文件上传
上传文件通常使用 FormData
对象:
<template>
<div>
<h1>Upload File</h1>
<input type="file" @change="uploadFile" />
</div>
</template>
<script>
import { ref } from 'vue';
import axios from '../utils/axios';
export default {
setup() {
const uploadFile = async (event) => {
const file = event.target.files[0];
const formData = new FormData();
formData.append('file', file);
try {
const response = await axios.post('/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
});
console.log('File uploaded:', response.data);
} catch (error) {
console.error(error);
}
};
return {
uploadFile
};
}
};
</script>
文件下载
下载文件可以通过处理 blob
数据:
<template>
<div>
<h1>Download File</h1>
<button @click="downloadFile">Download</button>
</div>
</template>
<script>
import { ref } from 'vue';
import axios from '../utils/axios';
export default {
setup() {
const downloadFile = async () => {
try {
const response = await axios.get('/download', {
responseType: 'blob'
});
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'file.txt'); // 替换为实际的文件名
document.body.appendChild(link);
();
link.remove();
} catch (error) {
console.error(error);
}
};
return {
downloadFile
};
}
};
</script>
封装 Axios 实例
在实际项目中,我们通常会对 Axios 进行封装,以便在整个项目中统一管理和使用。
创建 Axios 封装
// src/api/axiosInstance.js
import axios from 'axios';
const axiosInstance = axios.create({
baseURL: 'https://', // 替换为实际的 API URL
timeout: 10000,
});
axiosInstance.interceptors.request.use(
config => {
config.headers.Authorization = `Bearer ${localStorage.getItem('token')}`;
return config;
},
error => {
return Promise.reject(error);
}
);
axiosInstance.interceptors.response.use(
response => {
return response;
},
error => {
if (error.response && error.response.status === 401) {
console.error('Unauthorized, redirecting to login...');
}
return Promise.reject(error);
}
);
export default axiosInstance;
创建 API 服务
// src/api/userService.js
import axiosInstance from './axiosInstance';
export const getUsers = () => {
return axiosInstance.get('/users');
};
export const addUser = (user) => {
return axiosInstance.post('/users', user);
};
在组件中使用 API 服务
<template>
<div>
<h1>Users</h1>
<ul>
<li v-for="user in users" :key="user.id">{{ }}</li>
</ul>
<h1>Add User</h1>
<form @submit.prevent="handleAddUser">
<input v-model="" placeholder="Name" />
<button type="submit">Add</button>
</form>
</div>
</template>
<script>
import { ref, onMounted } from 'vue';
import { getUsers, addUser } from '../api/userService';
export default {
setup() {
const users = ref([]);
const newUser = ref({ name: '' });
const fetchUsers = async () => {
try {
const response = await getUsers();
users.value = response.data;
} catch (error) {
console.error(error);
}
};
const handleAddUser = async () => {
try {
const response = await addUser(newUser.value);
console.log('User added:', response.data);
fetchUsers(); // 刷新用户列表
} catch (error) {
console.error(error);
}
};
onMounted(fetchUsers);
return {
users,
newUser,
handleAddUser
};
}
};
</script>
结论
在 Vue 3 中使用 Axios 提供了丰富的功能来处理 HTTP 请求。从基本的 GET 和 POST 请求,到复杂的拦截器、错误处理、文件上传下载,Axios 都能轻松应对。通过本文的示例和讲解,希望您能更好地在 Vue 3 项目中应用 Axios,构建高效、可靠的前端应用。封装 Axios 实例和 API 服务能使代码更加简洁和可维护,是实际项目中的最佳实践之一。