vue3.0 + TypeScript 中使用 axios 同时进行二次封装

发布于:2025-08-01 ⋅ 阅读:(21) ⋅ 点赞:(0)

项目背景是vite搭建的vue3.0 + TypeScript 的项目,需要统一处理和统一维护就对axios进行了二次封装

axios的安装

npm install axios

定义http文件夹然后内部定义index.ts文件,内部开始封装

import axios, {type AxiosInstance} from "axios"; // AxiosInstance (axios的配置好的类型定义)
import qs from 'qs'; // 引入qs处理字符串的解析和序列化
// 定义 promise 类型
interface Result<T> {
    code:number;
    message:string;
    data: T;
    total?: number;
}
export default class request {
    axiosFun: AxiosInstance;  // 声明初始化的属性
    constructor() {
        // 设置连接地址和超时时间还有凭证
        this.axiosFun = axios.create({
            timeout: 1000 * 60 * 5,
            baseURL: "http://localhost:8888/",
            withCredentials: true,
        });
        // 统一增加请求头 也可以根据路径判断来添加请求头
        this.axiosFun.interceptors.request.use((config:any)=>{
            config.headers.token = localStorage.token || '';  
            return config;
        });
        // 请求返回后的统一处理 在这里可以处理返回的不同状态码
        this.axiosFun.interceptors.response.use((res:any)=>{
            if (res.headers["content-disposition"]) {
                return res;
            }
        },(err:any)=>{
            return Promise.resolve(err)
        });
    }
    //get请求
    public static getFetch(url: string, data?: any): Promise<Result<object>> {
        return new Promise((resolve, reject) => {
            new request().axiosFun.get(url, { params: data })
                .then((result:any) => {
                    resolve(result)
                })
                .catch((error:any) => {
                    reject(error)
                })
        })
    }
    //post json请求
    public static postJson<T>(url: string, data?: any): Promise<Result<object>> {
        return new Promise((resolve, reject) => {
            new request().axiosFun.post(url, JSON.stringify(data), { headers: {'Content-Type': 'application/json;charset=UTF-8'} })
                .then((result:any) => {
                    resolve(result)
                })
                .catch((error:any) => {
                    reject(error)
                })
        })
    }
    //post formData请求
    public static postFormData(url: string, data?: any): Promise<Result<object>> {
        return new Promise((resolve, reject) => {
            new request().axiosFun.post(url, data,{ headers: {'Content-Type': 'multipart/form-data'} })
                .then((result:any) => {
                    resolve(result)
                })
                .catch((error:any) => {
                    reject(error)
                })
        })
    }
    //post 表单请求
    public static postFormUrlencoded(url: string, data?: any): Promise<Result<object>> {
        return new Promise((resolve, reject) => {
            new request().axiosFun.post(url, qs.stringify(data, {indices: false})).then((result:any) => {
                resolve(result)
            }).catch((error:any) => {
                reject(error)
            })
        })
    }
    //post json请求 返回blob
    public static postFileJson<T>(url: T, data?: any): Promise<Result<object>> {
        return new Promise((resolve, reject) => {
            new request().axiosFun.post(url as string, JSON.stringify(data), { headers: {'Content-Type': 'application/json;charset=UTF-8'},responseType:'blob' })
                .then((result:any) => {
                    fileData(result);
                })
                .catch((error:any) => {
                    reject(error)
                })
        })
    }
    //get 下载文件 返回blob
    public static getFileFetch(url: string, data?: any): Promise<Result<object>> {
        return new Promise((resolve, reject) => {
            new request().axiosFun.get(url, { params: data,responseType: "blob" }).then((result:any) => {
                fileData(result);
            }).catch((error:any) => {
                reject(error)
            })
        })
    }
}
// 封装 a 标签下载文件
const fileData = (result:any)=>{
    let fileName:string = result.headers['content-disposition'].split('fileName=')[1]
    fileName = decodeURIComponent(fileName)
    let blob:Blob = new Blob([result.data])
    const fileUrl:string = URL.createObjectURL(blob)
    const download:any = document.createElement('a')
    download.download = fileName
    download.style.display = 'none'
    download.href = fileUrl
    document.body.appendChild(download)
    download.click()
    document.body.removeChild(download)
    URL.revokeObjectURL(fileUrl)
    return
}

http文件夹定义modules文件夹再定义homeApi.ts文件

import request from "@/http/request";  // 引入封装好的文件
export default class homeRequest {
    static messageList(params?: Object) {
        return request.postJson('/messageList', params)
    }
}

http文件夹内部定义api.ts文件

import HomeRequest from "@/http/modules/homeApi";
interface IHomeRequest {
  messageList(params?: Object): Promise<any>;
}
interface IApi {
  home: IHomeRequest;
}
export default class Api implements IApi {
  static home:IHomeRequest = HomeRequest
}

页面调用

import api from "@/http/api";
interface allInfo {
    [key:string]:any
}
interface Result<T> {
    code:number;
    message:string;
    data: T;
    total?: number;
}
const {code,data} = api.home.messageList(params) as Result<allInfo>
if(code === 200) {
  console.log(data)
}

网站公告

今日签到

点亮在社区的每一天
去签到