07 ts对axios封装

介绍

在项目开发中,进行网络请求目前我们较为常用的是axios,今天进行下封装,封装好处就不多说了

环境我用的是vue cli创建的项目

特点及难点是

1.实现了三种拦截器(全局,axios实例,某个接口)

2.实现接口返回类型

文件目录

07 ts对axios封装_第1张图片

 service/index: 在此文件创建axios实例

service/config/index: 配置文件

service/modules: 各个业务模块接口

service/request/index: 对axios封装

service/request/type: 类型声明

实现

service/index

import { BASE_URL, TIME_OUT } from "./config";
import GSRequest from "./request";
// 根据不同配置创建不同axios实例
const gsRequest = new GSRequest({
  baseURL: BASE_URL,
  timeout: TIME_OUT,
  interceptors: {
    requestSuccessFn(config) {
      // console.log("个别axios instance请求成功拦截");
      return config;
    },
    requestFailureFn(err) {
      return err;
    },
    responseSuccessFn(res) {
      return res;
    },
    responseFailureFn(err) {
      return err;
    },
  },
});

export default gsRequest;

service/config/index

export const BASE_URL = "http://httpbin.org";
export const TIME_OUT = 10000;

service/modules

import gsRequest from "../index";
// gsRequest
//   .request({
//     url: "/get",
//   })
//   .then((res) => {
//     console.log(res);
//   });

interface IPostResType {
  json: {
    id: string;
    name: string;
    age: number;
  };
  origin: string;
  url: string;
}

gsRequest
  .request({
    url: "/post",
    method: "post",
    data: {
      id: "124531",
      name: "zhao",
      age: 12,
    },
    interceptors: {
      requestSuccessFn(config) {
        // console.log("post个别请求拦截成功");
        return config;
      },
      responseSuccessFn(res) {
        // console.log("post个别请求响应成功拦截");
        return res;
      },
    },
  })
  .then((res) => {
    console.log(res);
    console.log(res.json);
  });

gsRequest
  .get({
    url: "get",
  })
  .then((res) => {
    console.log(res);
  });

service/request/index:

/**
 * 两个难点:
 * 1. 三种拦截器
 *   全局拦截器
 *   实例拦截器
 *   请求拦截器
 * 2. 返回结果类型处理<泛型>
 */

import axios from "axios";
import type { AxiosInstance } from "axios";
import { GSRequestConfig } from "./type";
// 用类封装的好处,可以创建多个axios实例
class GSRequest {
  instance: AxiosInstance;
  constructor(config: GSRequestConfig) {
    this.instance = axios.create(config);
    // 每个instance都添加拦截器
    this.instance.interceptors.request.use(
      (config) => {
        // loading/token
        // console.log("全局请求成功拦截");

        return config;
      },
      (err) => {
        // console.log("全局请求失败拦截");
        return err;
      }
    );
    this.instance.interceptors.response.use(
      (res) => {
        // console.log("全局响应成功拦截");

        return res.data;
      },
      (err) => {
        // console.log("全局响应失败拦截");
        return err;
      }
    );
    // 对单个instance添加拦截器
    this.instance.interceptors.request.use(
      config.interceptors?.requestSuccessFn,
      config.interceptors?.requestFailureFn
    );
    this.instance.interceptors.response.use(
      config.interceptors?.responseSuccessFn,
      config.interceptors?.responseFailureFn
    );
  }
  // 封装网络请求方法
  // 使用泛型确定返回data的具体类型
  request(config: GSRequestConfig) {
    // 单个instance中某个请求也可能会有单独拦截器,对config进行处理后重新赋值给config
    if (config.interceptors?.requestSuccessFn) {
      config = config.interceptors.requestSuccessFn(config);
    }
    return new Promise((resolve, reject) => {
      this.instance
        .request(config)
        .then((res) => {
          // 单个instance中某个请求也可能会有单独拦截器,对res进行处理后重新赋值给res
          if (config.interceptors?.responseSuccessFn) {
            res = config.interceptors.responseSuccessFn(res);
          }
          resolve(res);
        })
        .catch((err) => {
          reject(err);
        });
    });
  }
  get(config: GSRequestConfig) {
    return this.request({ ...config, method: "GET" });
  }
  post(config: GSRequestConfig) {
    return this.request({ ...config, method: "POST" });
  }
  delete(config: GSRequestConfig) {
    return this.request({ ...config, method: "DELETE" });
  }
  patch(config: GSRequestConfig) {
    return this.request({ ...config, method: "PATCH" });
  }
}

export default GSRequest;

service/request/type

import { AxiosRequestConfig, AxiosResponse } from "axios";
// 因为我们对返回类型做了泛型处理,所以res不能写死
interface GSInterceptors {
  requestSuccessFn?: (config: AxiosRequestConfig) => AxiosRequestConfig;
  requestFailureFn?: (err: any) => any;
  responseSuccessFn?: (res: T) => T;
  responseFailureFn?: (err: any) => any;
}
export interface GSRequestConfig extends AxiosRequestConfig {
  interceptors?: GSInterceptors;
}

欢迎交流讨论

你可能感兴趣的:(ts,typescript,前端)