How to use Class + TypeScript to encapsulate axios

提示:以下是本篇文章正文内容,下面案例可供参考

1. Install axios and ts related environment

This article is encapsulated in the react project, and of course it can also be used in the vue project.

npm install axios

2. Determine whether it is a production environment or an online environment

1. We take webpack as an example

Through process.env.NODE_ENV we can judge what kind of environment our project is in

let BASE_URL = ''
const TIME_OUT = 10000

if (process.env.NODE_ENV === 'development') {
  BASE_URL = 'http://localhost:3000'
} else if (process.env.NODE_ENV === 'production') {
  BASE_URL = 'http://localhost:3001'
} else if (process.env.NODE_ENV === 'test') {
  BASE_URL = 'http://localhost:3002'
}

export { BASE_URL, TIME_OUT }

2. Animation before installation request: NProgress

import NProgress from 'nprogress'
export default NProgress

3. Perform type restrictions

We have made some extensions to axios, we not only have interceptors for his instances, we can pass in interceptors to him, and we can also

To control whether this request animation is required or not.

import type { AxiosRequestConfig } from 'axios'

export interface LHRequestInterceptors {
  requestInterceptor?: (config: AxiosRequestConfig) => AxiosRequestConfig
  requestInterceptorCatch?: (error: any) => any
  responseInterceptor?: (res: any) => any
  responseInterceptorCatch?: (error: any) => any
}

export interface LHRequestConfig extends AxiosRequestConfig {
  interceptors?: LHRequestInterceptors
  showLoading?: boolean
}

4. Encapsulate class request tool class

import axios from 'axios'
import type { AxiosInstance } from 'axios'
import type { LHRequestConfig, LHRequestInterceptors } from './type'
import NProgress from './myNprogress'

const defaultLoading = true

class LHRequest {
  instance: AxiosInstance
  interceptors?: LHRequestInterceptors
  showLoading?: boolean

  constructor(config: LHRequestConfig) {
    this.instance = axios.create(config)
    this.interceptors = config.interceptors
    this.showLoading = config.showLoading ?? defaultLoading

    //所有实例的拦截器
    this.instance.interceptors.request.use(
      this.interceptors?.requestInterceptor,
      this.interceptors?.requestInterceptorCatch
    )

    this.instance.interceptors.response.use(
      this.interceptors?.responseInterceptorCatch,
      this.interceptors?.responseInterceptor
    )
    //全局的拦截器
    this.instance.interceptors.request.use(
      (config) => {
        if (this.showLoading) {
          NProgress.start()
        }
        return config
      },
      (err) => {
        return err
      }
    )

    this.instance.interceptors.response.use(
      (res) => {
        if (this.showLoading) {
          NProgress.done()
        }
        return res.data
      },
      (err) => {
        return err
      }
    )
  }
  request<T>(config: LHRequestConfig): Promise<T> {
    return new Promise((reslove, reject) => {
      if (config.interceptors?.requestInterceptor) {
        config = config.interceptors.requestInterceptor(config)
      }
      if (config.showLoading === false) {
        this.showLoading = config.showLoading
      }
      this.instance
        .request<any, T>(config)
        .then((res) => {
          if (config.interceptors?.responseInterceptor) {
            res = config.interceptors.responseInterceptor(res)
          }
          this.showLoading = true
          reslove(res)
        })
        .catch((err) => {
          this.showLoading = true
          reject(err)
          return err
        })
    })
  }
  get<T>(config: LHRequestConfig): Promise<T> {
    return this.request<T>({ ...config, method: 'GET' })
  }
  post<T>(config: LHRequestConfig): Promise<T> {
    return this.request<T>({ ...config, method: 'POST' })
  }
  delet<T>(config: LHRequestConfig): Promise<T> {
    return this.request<T>({ ...config, method: 'DELETE' })
  }
  patch<T>(config: LHRequestConfig): Promise<T> {
    return this.request<T>({ ...config, method: 'PATCH' })
  }
}
export default LHRequest

4. Create a new instance for easy management

// service的统一出口
import { BASE_URL, TIME_OUT } from './request/config'
import LHRequest from './request'
const lhRequest = new LHRequest({
  baseURL: BASE_URL,
  timeout: TIME_OUT,
  interceptors: {
    requestInterceptor: (config) => {
      console.log('成功的拦截')
      return config
    },
    requestInterceptorCatch: (err) => {
      return err
    },
    responseInterceptor: (res) => {
      return res
    },
    responseInterceptorCatch(err) {
      return err
    }
  }
})
export default lhRequest

5. How to call

lhRequest
    .get<banner>({
      url: '/dj/banner',
      showLoading: true
    })
    .then((res) => {
      console.log(res.data)
    })

Guess you like

Origin blog.csdn.net/m0_70718568/article/details/128519514
Recommended