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.ts
import 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.ts
import Axios from "./Axios";
import { AxiosInstance } from "./types";
// 创建一个axios的实例
function createInstance(): AxiosInstance {
let context: Axios = new Axios();
// this永远指向context,也就是new Axios
let instance = Axios.prototype.request.bind(context);
// 把axios的类的实例和原型上的方法都拷贝到instance
instance = 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.ts
export 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.ts
import { 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=123
if (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/