vue3+ts封装axios

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;
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员禅心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值