1、初始化项目

  1. // 初始化一个react+ts的项目
  2. npx create-react-app axios --typescript
  3. // 安装基础库
  4. yarn add axios @types/axios qs @types/qs parse-headers

2、文件夹结构

image.png

3、mock工具

3.1 json-server安装

  1. yarn add json-server -D

3.2 创建目录添加启动命令

image.png

image.png

4、代码编写

4.1 src/index.ts

  1. // src/index.ts
  2. import axios, { AxiosResponse, AxiosRequestConfig } from "./axios";
  3. const baseUrl = "http://localhost:8888";
  4. interface User {
  5. username: string;
  6. password: string;
  7. }
  8. let user: User = {
  9. username: "admin",
  10. password: "123",
  11. };
  12. axios({
  13. method: "get",
  14. url: baseUrl + "/get",
  15. params: user,
  16. })
  17. .then((response: AxiosResponse) => {
  18. console.log(response);
  19. })
  20. .catch((error: any) => {
  21. console.log(error);
  22. });

4.2 src/axios/index.ts

  1. // src/axios/index.ts
  2. import Axios from "./Axios";
  3. import { AxiosInstance } from "./types";
  4. // 创建一个axios的实例
  5. function createInstance(): AxiosInstance {
  6. let context: Axios = new Axios();
  7. // this永远指向context,也就是new Axios
  8. let instance = Axios.prototype.request.bind(context);
  9. // 把axios的类的实例和原型上的方法都拷贝到instance
  10. instance = Object.assign(instance, Axios.prototype, context);
  11. return instance as AxiosInstance;
  12. }
  13. let axios = createInstance();
  14. export default axios;
  15. export * from "./types";

4.3 src/axios/types.ts

  1. // src/axios/types.ts
  2. export interface PlainObject {
  3. [name: string]: any;
  4. }
  5. export type Methods = "get" | "GET" | "post" | "POST";
  6. // 请求参数
  7. export interface AxiosRequestConfig {
  8. url: string;
  9. method: Methods;
  10. params: any;
  11. }
  12. // axios.prototype.request方法的
  13. export interface AxiosInstance {
  14. <T = any>(config: AxiosRequestConfig): Promise<T>;
  15. }
  16. // 相应类型
  17. export interface AxiosResponse<T = any> {
  18. data: T;
  19. status: number;
  20. statusText: string;
  21. headers?: PlainObject;
  22. config?: AxiosRequestConfig;
  23. request?: XMLHttpRequest;
  24. }

4.4 src/axios/Axios.ts

  1. // src/axios/Axios.ts
  2. import { AxiosRequestConfig, AxiosResponse } from "./types";
  3. import qs from "qs";
  4. import parseHeaders from "parse-headers";
  5. export default class Axios {
  6. //T用来限制相应对象response里的data的类型
  7. request<T>(config: AxiosRequestConfig): Promise<AxiosResponse<T>> {
  8. return this.dispatchRequest(config);
  9. }
  10. // 定义一个开发请求的方法
  11. dispatchRequest<T>(config: AxiosRequestConfig): Promise<AxiosResponse<T>> {
  12. return new Promise<AxiosResponse<T>>(function (resolve, reject) {
  13. let { method, url, params } = config;
  14. let request = new XMLHttpRequest();
  15. // {name:'admin',password:'123'}转成?name=admin&password=123
  16. if (params && typeof params === "object") {
  17. params = qs.stringify(params);
  18. }
  19. // 判断url有无参数
  20. url += ((url.indexOf("?") === -1 ? "?" : "&") + params);
  21. request.open(method, url, true);
  22. // 返回json类型
  23. request.responseType = 'json'
  24. request.onreadystatechange = function () {
  25. if (request.readyState === 4) {
  26. if (request.status >= 200 && request.status < 300) {
  27. let response: AxiosResponse<T> = {
  28. data: request.response ? request.response : request.responseText,
  29. status: request.status,
  30. statusText: request.statusText,
  31. headers: parseHeaders(request.getAllResponseHeaders()),
  32. config,
  33. request,
  34. };
  35. resolve(response)
  36. } else {
  37. reject("请求失败");
  38. }
  39. }
  40. };
  41. request.send();
  42. });
  43. }
  44. }

5、实现效果

image.png

6、源代码

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