vue3 + ts + axios封装,接口返回数据有代码提示

前言

有过工作经验的小伙伴应该对axios二次封装比较熟悉,但是加入ts后就比较犯难,被ts的数据格式校验搞的头大,接下来就简单分析一下axios,作者版本"axios": "^1.6.8",

引入axios以及实例化
import axios from "axios";
import type { InternalAxiosRequestConfig, AxiosError, AxiosRequestConfig } from "axios"

const service = axios.create({
    baseURL: import.meta.env.BASE_URL,
    timeout: 30000
})
设置请求拦截器以及了解 InternalAxiosRequestConfig内置数据类型

首先,我们找到axios包下面index.d.ts声明文件

interceptors.request就是我们要设置的请求拦截器,接下来再看InternalAxiosRequestConfig类型设置

InternalAxiosRequestConfig继承了AxiosRequestConfig类型并配置了headers属性

接下来实现一下请求拦截器的代码

service.interceptors.request.use(
    (config: InternalAxiosRequestConfig) => {
        const token = getToken()
        // 配置请求权限
        if (token) {
            config.headers["Authorization"] = 'Bearer ' + token
        }
        return config
    },
    (error: AxiosError) => {
        Promise.reject(error)
    }
)

如果将InternalAxiosRequestConfig换成了AxiosRequestConfig,编辑器会给出错误提示

设置响应拦截器,响应数据有代码提示

还是先看源码

axios实例,request接受一个泛型T, 返回一个Promise, D为请求参数data泛型约束,这里不做介绍。再看这个AxiosResponse<T>

这个泛型T也就是request接受的第一个泛型T用于约束response中的data

代码实现

type Data<T> = {
    status: number,
    msg: string,
    result: T
}

// 暴露一个异步函数,接受一个泛型T传入Data,再将Data<T>传入service.request

export default <T>(config: AxiosRequestConfig) => {
    return new Promise<Data<T>>((res, rej) => {
        service
            .request<Data<T>>(config)
            .then((response) => {
                // 打印结果如下
                console.log(response);
                // 请求成功 返回接口数据
                res(response.data);
                // 请求失败 rej()
            })
            .catch((err: any) => {
                console.log(err);
                //  处理错误逻辑
                rej(err);
            });
    });
};

代码测试

import request from "@/utils/request";
import type { UserInfo } from '../types/user'

export const getUserInfo = () => {
    // 如果返回的是数组格式 UserInfo改为UserInfo[]
    return request<UserInfo>({
        method: 'get',
        url: '/api/userInfo',
    })
}

ps: 如果代码修改完成,接口返回数据还没有提示,可以重启编辑器

完整代码
import axios from "axios";
import type { InternalAxiosRequestConfig, AxiosError, AxiosRequestConfig, AxiosResponse } from "axios"
import { getToken } from "./token";

const service = axios.create({
    baseURL: import.meta.env.BASE_URL,
    timeout: 30000
})

service.interceptors.request.use(
    (config: InternalAxiosRequestConfig) => {
        const token = getToken()
        // 配置请求权限
        if (token) {
            config.headers["Authorization"] = 'Bearer ' + token
        }
        return config
    },
    (error: AxiosError) => {
        Promise.reject(error)
    }
)

// 在这里没有找到泛型约束的方法
service.interceptors.response.use()

// 根据实际情况自行修改
type Data<T> = {
    status: number,
    msg: string,
    result: T
}

// 暴露一个异步函数,接受一个泛型T传入Data,再将Data<T>传入service.request

export default <T>(config: AxiosRequestConfig) => {
    return new Promise<Data<T>>((res, rej) => {
        service
            .request<Data<T>>(config)
            .then((response) => {
                // 打印结果如下
                console.log(response);
                // 逻辑自行处理
                if (response.data.status === 0) {
                    // 返回接口数据
                    res(response.data);
                } else {
                    rej(response.data)
                }

            })
             // AxiosError同样支持泛型约束,第一个泛型参数 约束err.response.data
            .catch((err: AxiosError<Data<T>) => {
                console.log(err);
                //  处理错误逻辑
                rej(err);
            });
    });
};

本篇文章到这里就结束了,希望对小伙伴们有帮助,如果有更加优雅的实现方式,欢迎评论区留言

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值