在 Vue 3 项目中,结合 TypeScript 和 Axios 封装一个通用的 HTTP 请求工具类,可以提高代码的可维护性和复用性。以下是一个完整的封装示例:
1. 安装 Axios
如果项目中没有安装 Axios,可以通过以下命令安装:
npm install axios
2. 创建 Axios 封装工具类
在 src/utils 目录下创建一个文件 http.ts,用于封装 Axios:
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
// 定义接口返回的数据结构
interface ApiResponse<T = any> {
code: number;
message: string;
data: T;
}
class HttpClient {
private instance: AxiosInstance;
constructor(baseURL: string) {
this.instance = axios.create({
baseURL,
timeout: 10000, // 请求超时时间
headers: {
'Content-Type': 'application/json',
},
});
// 请求拦截器
this.instance.interceptors.request.use(
(config) => {
// 在发送请求之前可以做一些处理,比如添加 token
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
// 响应拦截器
this.instance.interceptors.response.use(
(response: AxiosResponse<ApiResponse>) => {
// 对响应数据做一些处理
if (response.data.code !== 200) {
console.error('请求失败:', response.data.message);
return Promise.reject(response.data.message);
}
return response.data.data; // 直接返回实际数据
},
(error) => {
// 对错误响应做一些处理
console.error('请求出错:', error.message);
return Promise.reject(error);
}
);
}
// 封装 GET 请求
public async get<T>(url: string, config?: AxiosRequestConfig): Promise<T> {
return this.instance.get(url, config);
}
// 封装 POST 请求
public async post<T>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
return this.instance.post(url, data, config);
}
// 封装 PUT 请求
public async put<T>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
return this.instance.put(url, data, config);
}
// 封装 DELETE 请求
public async delete<T>(url: string, config?: AxiosRequestConfig): Promise<T> {
return this.instance.delete(url, config);
}
}
// 创建实例并导出
const baseURL = 'https://api.example.com'; // 替换为你的 API 地址
const http = new HttpClient(baseURL);
export default http;
3. 在组件中使用封装的 Axios
在 Vue 组件中,可以直接导入并使用封装好的 http 工具类:
<template>
<div>
<button @click="fetchData">获取数据</button>
<button @click="submitData">提交数据</button>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import http from '@/utils/http';
export default defineComponent({
methods: {
async fetchData() {
try {
const data = await http.get<{ id: number; name: string }>('/api/data');
console.log('获取到的数据:', data);
} catch (error) {
console.error('获取数据失败:', error);
}
},
async submitData() {
try {
const response = await http.post('/api/submit', { name: 'John', age: 25 });
console.log('提交成功:', response);
} catch (error) {
console.error('提交失败:', error);
}
},
},
});
</script>
4. 全局挂载 Axios 实例(可选)
如果你希望在整个项目中更方便地使用封装的 Axios 实例,可以将其挂载到 Vue 的全局属性上。
在 src/main.ts 中:
import { createApp } from 'vue';
import App from './App.vue';
import http from './utils/http';
const app = createApp(App);
// 挂载到全局属性
app.config.globalProperties.$http = http;
app.mount('#app');
在组件中使用:
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
methods: {
async fetchData() {
try {
const data = await this.$http.get('/api/data');
console.log('获取到的数据:', data);
} catch (error) {
console.error('获取数据失败:', error);
}
},
},
});
</script>
5. 添加类型支持(可选)
为了更好的 TypeScript 支持,可以在 src/types 目录下定义全局类型:
// src/types/http.d.ts
import { ComponentCustomProperties } from 'vue';
import HttpClient from '@/utils/http';
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
$http: HttpClient;
}
}
6. 总结
通过以上步骤,我们实现了一个基于 Vue 3 和 TypeScript 的 Axios 封装工具类。它具有以下特点:
- 支持请求和响应拦截器。
- 提供了 GET、POST、PUT、DELETE 等常用方法的封装。
- 支持 TypeScript 类型推断,提高代码的健壮性。
- 可以全局挂载,方便在项目中复用。
你可以根据项目需求进一步扩展和优化这个封装工具类,例如添加文件上传、下载等功能。