数据请求(Axios 与 Vue)
在 Vue 3 setup 下使用 axios 时,可以将 axios 独立于 Vue 组件,放置在单独的文件或目录中,统一处理 API 请求。这样可以提高代码的可维护性和复用性。接下来,我们将详细介绍如何将 axios 独立出来进行全局配置、请求拦截器和响应拦截器的使用、同步与异步请求的处理,以及如何进行全局异常捕捉和处理。
一、项目结构
首先,我们为 axios 创建一个独立的文件夹,将 axios 的配置和 API 请求逻辑封装起来:
text
├── src
│ ├── api
│ │ ├── axiosConfig.js # axios配置文件
│ │ ├── userApi.js # 用户相关API请求
│ │ ├── postApi.js # 文章相关API请求
│ ├── components
│ ├── views
│ ├── App.vue
│ └── main.js二、axiosConfig.js:axios 全局配置与拦截器
首先,我们在 api/axiosConfig.js 中统一配置 axios。这包括设置基础 URL、超时、请求拦截器、响应拦截器以及全局异常处理。
js
// api/axiosConfig.js
import axios from 'axios';
// 创建 axios 实例
const service = axios.create({
baseURL: 'https://jsonplaceholder.typicode.com', // 基础URL
timeout: 10000, // 请求超时时间
});
// 请求拦截器
service.interceptors.request.use(
(config) => {
// 在请求之前,可以在这里加入 token 或其他认证信息
const token = localStorage.getItem('token');
if (token) {
config.headers['Authorization'] = `Bearer ${token}`;
}
return config;
},
(error) => {
// 请求错误处理
console.error('请求拦截错误: ', error);
return Promise.reject(error);
}
);
// 响应拦截器
service.interceptors.response.use(
(response) => {
// 对响应数据做一些处理
return response.data;
},
(error) => {
// 统一的错误处理
if (error.response) {
switch (error.response.status) {
case 401:
alert('未授权,请登录');
window.location.href = '/login'; // 跳转到登录页面
break;
case 404:
alert('请求地址未找到');
break;
case 500:
alert('服务器错误,请稍后重试');
break;
default:
alert(`发生错误:${error.message}`);
}
}
return Promise.reject(error);
}
);
export default service;三、封装 API 请求
我们可以在 api/ 目录下创建多个文件来处理不同模块的 API 请求,示例如下:
1. 用户相关 API (userApi.js)
js
// api/userApi.js
import axios from './axiosConfig';
// 获取用户列表
export function getUsers() {
return axios.get('/users');
}
// 获取单个用户
export function getUserById(id) {
return axios.get(`/users/${id}`);
}2. 文章相关 API (postApi.js)
js
// api/postApi.js
import axios from './axiosConfig';
// 获取文章列表
export function getPosts() {
return axios.get('/posts');
}
// 获取单篇文章
export function getPostById(id) {
return axios.get(`/posts/${id}`);
}四、在组件中使用封装的 API
接下来,我们在 Vue 组件中使用这些封装好的 API。以用户数据的展示为例:
vue
<template>
<div>
<h1>用户列表</h1>
<ul>
<li v-for="user in users" :key="user.id">{{ user.name }}</li>
</ul>
<p v-if="error">{{ error }}</p>
</div>
</template>
<script>
import { ref, onMounted } from 'vue';
import { getUsers } from '../api/userApi'; // 导入封装的API
export default {
setup() {
const users = ref([]);
const error = ref(null);
// 在组件挂载时调用 API 获取用户列表
onMounted(async () => {
try {
users.value = await getUsers();
} catch (err) {
error.value = '获取用户列表失败';
console.error(err);
}
});
return { users, error };
}
};
</script>五、同步与异步请求的处理
axios 默认是异步的,我们可以通过 async/await 来处理异步请求,也可以在需要时处理同步请求。
1. 异步请求
异步请求使用 async/await 处理,代码更加简洁。
js
async function fetchData() {
try {
const response = await axios.get('/data');
console.log('数据:', response);
} catch (error) {
console.error('请求失败:', error);
}
}2. 同步请求
虽然 axios 本质上是异步的,但我们可以通过 async/await 实现同步请求的效果,即等待请求完成后再执行后续操作:
js
async function fetchDataSync() {
try {
const response = await axios.get('/data');
console.log('同步数据:', response);
} catch (error) {
console.error('请求失败:', error);
}
}六、全局异常捕捉与处理
为了在全局范围内捕捉异常,我们已经在 axiosConfig.js 中通过响应拦截器统一处理了错误。例如,遇到 401 未授权错误时,自动跳转到登录页面。
可以在具体 API 请求的调用处进一步处理异常,确保所有请求的错误都能得到合适的处理:
js
async function fetchData() {
try {
const response = await getPosts();
console.log('文章数据:', response);
} catch (error) {
console.error('获取文章数据失败:', error);
// 可以根据具体错误类型弹出不同提示
alert('获取数据失败,请稍后重试');
}
}七、总结
- 全局配置:将
axios的基础配置和拦截器统一放在axiosConfig.js中,便于管理和维护。 - 拦截器:请求拦截器可用于添加 Token 等信息,响应拦截器可用于处理统一的错误逻辑。
- API 模块化:将不同业务逻辑的 API 封装在不同的文件中,提高代码的可读性和复用性。
- 同步与异步:通过
async/await简化异步请求的代码结构。 - 全局异常捕捉:通过拦截器统一处理响应错误,确保异常不会导致应用崩溃。
这种将 axios 独立封装的方式不仅可以提高代码复用性,还能方便对请求进行全局化管理,有助于大型项目的开发。