1、初始化项目
// 初始化一个react+ts的项目npx create-react-app axios --typescript// 安装基础库yarn add axios @types/axios qs @types/qs parse-headers
2、文件夹结构

3、mock工具
3.1 json-server安装
yarn add json-server -D
3.2 创建目录添加启动命令


4、代码编写
4.1 src/index.ts
// src/index.tsimport axios, { AxiosResponse, AxiosRequestConfig } from "./axios";const baseUrl = "http://localhost:8888";interface User {username: string;password: string;}let user: User = {username: "admin",password: "123",};axios({method: "get",url: baseUrl + "/get",params: user,}).then((response: AxiosResponse) => {console.log(response);}).catch((error: any) => {console.log(error);});
4.2 src/axios/index.ts
// src/axios/index.tsimport Axios from "./Axios";import { AxiosInstance } from "./types";// 创建一个axios的实例function createInstance(): AxiosInstance {let context: Axios = new Axios();// this永远指向context,也就是new Axioslet instance = Axios.prototype.request.bind(context);// 把axios的类的实例和原型上的方法都拷贝到instanceinstance = Object.assign(instance, Axios.prototype, context);return instance as AxiosInstance;}let axios = createInstance();export default axios;export * from "./types";
4.3 src/axios/types.ts
// src/axios/types.tsexport interface PlainObject {[name: string]: any;}export type Methods = "get" | "GET" | "post" | "POST";// 请求参数export interface AxiosRequestConfig {url: string;method: Methods;params: any;}// axios.prototype.request方法的export interface AxiosInstance {<T = any>(config: AxiosRequestConfig): Promise<T>;}// 相应类型export interface AxiosResponse<T = any> {data: T;status: number;statusText: string;headers?: PlainObject;config?: AxiosRequestConfig;request?: XMLHttpRequest;}
4.4 src/axios/Axios.ts
// src/axios/Axios.tsimport { AxiosRequestConfig, AxiosResponse } from "./types";import qs from "qs";import parseHeaders from "parse-headers";export default class Axios {//T用来限制相应对象response里的data的类型request<T>(config: AxiosRequestConfig): Promise<AxiosResponse<T>> {return this.dispatchRequest(config);}// 定义一个开发请求的方法dispatchRequest<T>(config: AxiosRequestConfig): Promise<AxiosResponse<T>> {return new Promise<AxiosResponse<T>>(function (resolve, reject) {let { method, url, params } = config;let request = new XMLHttpRequest();// {name:'admin',password:'123'}转成?name=admin&password=123if (params && typeof params === "object") {params = qs.stringify(params);}// 判断url有无参数url += ((url.indexOf("?") === -1 ? "?" : "&") + params);request.open(method, url, true);// 返回json类型request.responseType = 'json'request.onreadystatechange = function () {if (request.readyState === 4) {if (request.status >= 200 && request.status < 300) {let response: AxiosResponse<T> = {data: request.response ? request.response : request.responseText,status: request.status,statusText: request.statusText,headers: parseHeaders(request.getAllResponseHeaders()),config,request,};resolve(response)} else {reject("请求失败");}}};request.send();});}}
5、实现效果

6、源代码
代码地址:https://gitee.com/linhexs/handwritten-axios/tree/1.get-request/
