1.目录层级

  • service
    • request
      • config.ts
      • index.ts
      • types.ts
    • index.ts

2. 具体代码

2.0 安装axios

npm i axios@next

2.1 request/types

import type { AxiosRequestConfig, AxiosResponse } from "axios";

// 自定义拦截器type
export interface CustomInterceptors<T = AxiosResponse> {
  requestInterceptor?: (config: AxiosRequestConfig) => AxiosRequestConfig;
  requestInterceptorCatch?: (err: any) => any;
  responsetInterceptor?: (config: T) => T;
  responsetInterceptorCatch?: (err: any) => any;
}

// 自定义请求设置type
export interface CustomRequestConfig<T = AxiosResponse> extends AxiosRequestConfig {
  interceptors?: CustomInterceptors<T>;
  showLoading?: boolean;
}

2.2 request/config

// 配置环境变量

// timeout
export const TIME_OUT = 10000;

// baseUrl
export const API_BASE_URL = process.env.VUE_APP_BASE_URL;

2.3 request/index

import axios from "axios";
import type { AxiosInstance } from "axios";
import { ElLoading } from "element-plus";
import type { LoadingInstance } from "element-plus/lib/components/loading/src/loading";
import NProgress from "nprogress";
import "nprogress/nprogress.css";

import { CustomInterceptors, CustomRequestConfig } from "./type";

// 默认loading为false
const DEFAULT_LOADING = false;

// http请求
class HttpRequest {
  // axios实例
  instance: AxiosInstance;
  // 自定义拦截器
  interceptors?: CustomInterceptors;
  showLoading: boolean;
  loading?: LoadingInstance;

  constructor(config: CustomRequestConfig) {
    this.instance = axios.create(config);
    this.showLoading = config.showLoading ?? DEFAULT_LOADING;
    this.interceptors = config.interceptors;

    // 实例拦截器
    this.instance.interceptors.request.use(
      this.interceptors?.requestInterceptor,
      this.interceptors?.requestInterceptorCatch,
    );
    this.instance.interceptors.response.use(
      this.interceptors?.responsetInterceptor,
      this.interceptors?.responsetInterceptorCatch,
    );

    // 全局拦截器, 添加所有的实例都有的拦截器
    // request
    this.instance.interceptors.request.use(
      (config) => {
        // 加载进度条
        NProgress.start();
        // 展示loading
        if (this.showLoading) {
          this.loading = ElLoading.service({
            lock: true,
            text: "正在加载...",
            background: "rgba(0, 0, 0, 0.5)",
          });
        }
        return config;
      },
      (error) => {
        return error;
      },
    );
    // response
    this.instance.interceptors.response.use(
      (res) => {
        // 移除loading
        this.loading?.close();
        // 关闭进度条
        NProgress.done();
        return res;
      },
      (error) => {
        // 移除loading
        this.loading?.close();
        // 关闭进度条
        NProgress.done();
        return error;
      },
    );
  }

  /** 封装请求方法 */
  // request
  request<T = any>(config: CustomRequestConfig<T>): Promise<T> {
    return new Promise((resolve, reject) => {
      // request 对config处理
      if (config.interceptors?.requestInterceptor) {
        //如果有requestInterceptor,就执行一下
        config = config.interceptors.requestInterceptor(config);
      }
      // 判断是否showLoading
      if (config.showLoading === true) {
        this.showLoading = config.showLoading;
      }

      this.instance
        .request<any, T>(config)
        .then((res) => {
          // response 对数据处理
          if (config.interceptors?.responsetInterceptor) {
            res = config.interceptors.responsetInterceptor(res);
          }

          // 重置showLoading
          this.showLoading = DEFAULT_LOADING;
          resolve(res);
        })
        .catch((error) => {
          // 重置showLoading
          this.showLoading = DEFAULT_LOADING;
          reject(error);
        });
    });
  }

  // get
  get<T = any>(config: CustomRequestConfig<T>): Promise<T> {
    return this.request<T>({ ...config, method: "GET" });
  }

  // post
  post<T = any>(config: CustomRequestConfig<T>): Promise<T> {
    return this.request<T>({ ...config, method: "POST" });
  }

  // put
  put<T = any>(config: CustomRequestConfig<T>): Promise<T> {
    return this.request<T>({ ...config, method: "PUT" });
  }

  // delete
  delete<T = any>(config: CustomRequestConfig<T>): Promise<T> {
    return this.request<T>({ ...config, method: "DELETE" });
  }
}

export default HttpRequest;

2.4 service/index

// 统一管理 service
import HttpRequest from "./request";
import { API_BASE_URL, TIME_OUT } from "./request/config";
import { ElMessage } from "element-plus";

const httpRequest = new HttpRequest({
  baseURL: API_BASE_URL,
  timeout: TIME_OUT,

  // 实例拦截器
  interceptors: {
    requestInterceptor(config) {
      return config;
    },
    requestInterceptorCatch(error) {
      return error;
    },

    responsetInterceptor(res) {
      console.log(res.data);
      return res.data;
    },
    responsetInterceptorCatch(error) {
      ElMessage.error("当前网络错误,请稍后再试");
      return error;
    },
  },
});

export default httpRequest;
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐