在项目中使用TS封装 axios,一次封装永久使用

简介: 在项目中使用TS封装 axios,一次封装永久使用

安装axios


yarn add axios

区分开发环境


  • 方式一:可以自己手动修改,但是不推荐
  • 方式二:根据 process.env.NODE_ENV 区分(推荐)
  • 方式三:根据 vue-cli 脚手架的 env配置不同开发环境,详情可以看vue-cli官方文档介绍
// src/service/request/config.ts
// 根据process.env.NODE_ENV 区分
// 开发环境: development
// 生成环境:production
// 测试环境: test
let BASE_URL = ''
const TIME_OUT = 10000
if (process.env.NODE_ENV === 'development') {
  // 这里BASE_URL 后地址根据实际项目服务器地址填写,这里是示例
  BASE_URL = 'http://123.207.32.32:8000'
} else if (process.env.NODE_ENV === 'production') {
  BASE_URL = 'http://elva.org/prod'
} else {
  BASE_URL = 'http://elva.org/test'
}
export { BASE_URL, TIME_OUT }

实现最基础的封装

//  src/service/request/index.ts
import axios from 'axios'
import type { AxiosInstance, AxiosResponse,AxiosRequestConfig } from 'axios'
class XDRequest {
  // axios 实例
  instance: AxiosInstance
   constructor(config: AxiosRequestConfig) {
    this.instance = axios.create(config)
  }
  request(config: AxiosRequestConfig): void {
   return this.instance.request(config)
      }
}
export default XDRequest

注意:这里封装一个类,是因为类可以new出多个实例


封装拦截器


==注意:==这里的封装思路是

微信图片_20221011145118.png

axios 提供的AxiosRequestConfig 类型是不允许我们传入拦截器的,这个时候需要我们自己定义一个接口,使改造后的接口继承AxiosRequestConfig

// src/service/request/type.ts
import type { AxiosRequestConfig, AxiosResponse } from 'axios'
export interface XDRequestInterceptors {
  requestIntercetor?: (config: AxiosRequestConfig) => AxiosRequestConfig
  requestIntercetorCatch?: (error: any) => any
  responseInterceptor?: (res: AxiosResponse) => AxiosResponse
  responseInterceptorCatch?: (error: any) => any
}
export interface XDRequestConfig extends AxiosRequestConfig {
  interceptors?: XDRequestInterceptors
}

1. 类拦截器


只需要在类中在axios.create()创建的实例中调用 interceptors中两个拦截器

image-20220723172447949

完整代码:

//  src/service/request/index.ts
import axios from 'axios'
import type { AxiosInstance, AxiosResponse } from 'axios'
import type { XDRequestInterceptors, XDRequestConfig } from './type'
class XDRequest {
  // axios 实例
  instance: AxiosInstance
   constructor(config: AxiosRequestConfig) {
    this.instance = axios.create(config)
     // 全局拦截器
    this.instance.interceptors.request.use(
      (config: XDRequestConfig) => {
        console.log('所有的实例都有的拦截器: 请求成功拦截')
        return config
      },
      //  请求失败拦截
      (err: any) => err
    )
    this.instance.interceptors.response.use(
      (res: AxiosResponse) => {
        console.log('所有实例都有的拦截器:响应成功拦截')
        return res
      },
      // 响应失败拦截
      (err: any) => err
    )
  }
  request(config: AxiosRequestConfig): void {
   return this.instance.request(config)
      }
}
export default XDRequest

2. 实例拦截器


image-20220723172348130

完整代码:

//  src/service/request/index.ts
import axios from 'axios'
import type { AxiosInstance, AxiosResponse } from 'axios'
import type { XDRequestInterceptors, XDRequestConfig } from './type'
class XDRequest {
  // axios 实例
  instance: AxiosInstance
   // 拦截器对象
  interceptorsObj?: XDRequestInterceptors
  constructor(config: AxiosRequestConfig) {
    this.instance = axios.create(config)
    // 实例拦截器
    this.interceptorsObj = config.interceptors
    this.instance.interceptors.request.use(
      this.interceptorsObj?.requestIntercetor,
      this.interceptorsObj?.requestIntercetorCatch
    )
    this.instance.interceptors.response.use(
      this.interceptorsObj?.responseInterceptor,
      this.interceptorsObj?.responseInterceptorCatch
    )
   // 全局拦截器(所有实例都有的拦截器)  
    this.instance.interceptors.request.use(
      (config: XDRequestConfig) => {
        console.log('所有的实例都有的拦截器: 请求成功拦截')
        return config
      },
      //  请求失败拦截
      (err: any) => err
    )
    this.instance.interceptors.response.use(
      (res: AxiosResponse) => {
        console.log('所有实例都有的拦截器:响应成功拦截')
        return res
      },
      // 响应失败拦截
      (err: any) => err
    )
  }
  request(config: AxiosRequestConfig): void {
   return this.instance.request(config)
      }
}
export default XDRequest

3. 接口(单一方法)拦截器


image-20220723172629476

完整代码:

import axios from 'axios'
import type { AxiosInstance, AxiosResponse } from 'axios'
import type { XDRequestInterceptors, XDRequestConfig } from './type'
class XDRequest {
  // axios 实例
  instance: AxiosInstance
  // 拦截器对象
  interceptorsObj?: XDRequestInterceptors
  // 使用拦截器
  constructor(config: XDRequestConfig) {
    this.instance = axios.create(config)
    // 1. 使用实例拦截器
    this.interceptorsObj = config.interceptors
    this.instance.interceptors.request.use(
      this.interceptorsObj?.requestIntercetor,
      this.interceptorsObj?.requestIntercetorCatch
    )
    this.instance.interceptors.response.use(
      this.interceptorsObj?.responseInterceptor,
      this.interceptorsObj?.responseInterceptorCatch
    )
    // 2. 全局拦截器(所有实例都有的拦截器)
    this.instance.interceptors.request.use(
      (config: XDRequestConfig) => {
        console.log('所有的实例都有的拦截器: 请求成功拦截')
        return config
      },
      //  请求失败拦截
      (err: any) => err
    )
    this.instance.interceptors.response.use(
      (res: AxiosResponse) => {
        console.log('所有实例都有的拦截器:响应成功拦截')
        return res
      },
      // 响应失败拦截
      (err: any) => err
    )
  }
  // 3. 为单个请求添加拦截器
  request(config: XDRequestConfig): void {
    // 如果我们为单个请求添加拦截器,这里使用单个请求的拦截
    if (config.interceptors?.requestIntercetor) {
      config = config.interceptors.requestIntercetor(config)
    }
    this.instance.request(config).then((res) => {
      // 如果我们为单个响应添加拦截器,这里使用单个响应的拦截
      if (config.interceptors?.responseInterceptor) {
        res = config.interceptors.responseInterceptor(res)
      }
      console.log(res)
    })
  }
}
export default XDRequest

测试:

// src/service/index.ts
// 测试实例拦截器
import XDRequest from './request'
import { BASE_URL, TIME_OUT } from './request/config'
const xdRequest = new XDRequest({
  baseURL: BASE_URL,
  timeout: TIME_OUT,
  interceptors: {
    requestIntercetor: (config) => {
      console.log('请求成功拦截')
      return config
    },
    requestIntercetorCatch: (err) => {
      console.log('请求拦截失败')
      return err
    },
    responseInterceptor: (res) => {
      console.log('响应成功拦截')
      return res
    },
    responseInterceptorCatch: (err) => {
      console.log('响应失败的拦截')
      return err
    }
  }
})
export default xdRequest
// 在整个mian.ts添加代码测试全局拦截器
import xdRequest from './service'
xdRequest.request({
  url: '/home/multidata',
  method: 'GET',
  interceptors: {
    requestIntercetor: (config) => {
      console.log('单独请求的config')
      return config
    }
  }
})

结果:

微信图片_20221011145406.png

相关文章
|
9天前
|
资源调度 JavaScript 前端开发
vue-element-admin 综合开发四:axios安装和封装、mock安装/学习/使用
这篇文章是关于如何在Vue项目中使用axios进行网络请求、二次封装axios以及使用mockjs模拟响应数据的教程。
32 1
vue-element-admin 综合开发四:axios安装和封装、mock安装/学习/使用
|
9天前
vue3 + Ts 中 使用 class 封装 axios
【10月更文挑战第8天】
59 1
|
12天前
vue3 + Ts 中 使用 class 封装 axios
【10月更文挑战第5天】
75 1
|
4天前
|
前端开发 JavaScript API
自己动手封装axios通用方法并上传至私有npm仓库:详细步骤与实现指南
自己动手封装axios通用方法并上传至私有npm仓库:详细步骤与实现指南
23 0
|
14天前
|
资源调度 JavaScript
|
2月前
|
JavaScript 前端开发
【Vue面试题二十五】、你了解axios的原理吗?有看过它的源码吗?
这篇文章主要讨论了axios的使用、原理以及源码分析。 文章中首先回顾了axios的基本用法,包括发送请求、请求拦截器和响应拦截器的使用,以及如何取消请求。接着,作者实现了一个简易版的axios,包括构造函数、请求方法、拦截器的实现等。最后,文章对axios的源码进行了分析,包括目录结构、核心文件axios.js的内容,以及axios实例化过程中的配置合并、拦截器的使用等。
【Vue面试题二十五】、你了解axios的原理吗?有看过它的源码吗?
|
14天前
|
缓存 JavaScript 搜索推荐
|
2月前
|
JavaScript 前端开发
【Vue面试题二十七】、你了解axios的原理吗?有看过它的源码吗?
文章讨论了Vue项目目录结构的设计原则和实践,强调了项目结构清晰的重要性,提出了包括语义一致性、单一入口/出口、就近原则、公共文件的绝对路径引用等原则,并展示了单页面和多页面Vue项目的目录结构示例。
|
1月前
|
JavaScript 前端开发 开发者
vue中使用axios请求post接口,请求会发送两次
vue中使用axios请求post接口,请求会发送两次
|
4天前
|
前端开发 JavaScript 安全
在vue前端开发中基于refreshToken和axios拦截器实现token的无感刷新
在vue前端开发中基于refreshToken和axios拦截器实现token的无感刷新
28 4