4-封装axios

源码github连接:baojinghui/MyAxios (github.com)

1,为什么要封装axios ,因为当一个库不维护时,便于在封装的地方把不维护的库替换掉

2,因为axios返回的是一个实例对象,所以只能这一个实例上修改。但是我们的接口有两种baseUrl,就可以通过封装,不同的接口创建新的实例去配置,不同实例互不干扰。

3,配置拦截器,给不同的实例配置不同的拦截器,支持以对象形式接受多个拦截器配置

4,一般情况下一个实例就够用了,在大行项目中可以使用到多个实例

目录结构:

类型声明:

/*-------------------------  TS封装拦截器的接口  -------------------------------------*/

//导入axios的  实例的类型      请求参数的类型      响应数据的类型
import type { AxiosRequestConfig } from 'axios'

//扩展拦截器的类型,支持传入一个对象,对象中可同时传入多个回调,可以同时包含响应器和拦截器的配置
export interface MyInterceptors {
  //请求拦截器和请求拦截器捕获错误的类型
  resquestInterceptors?: (config: AxiosRequestConfig) => AxiosRequestConfig
  resquestInterceptorsCatch?: (err: any) => any
  //响应拦截器和响应拦截器捕获错误的类型
  responseInterceptors?: (config: any) => any //AxiosResponse
  responseInterceptorsCatch?: (err: any) => any
}
//类型扩展,把axios上的类型,扩展到自己定义的接口上,使请求参数支持传入一个对象
export interface MyRequestConfig extends AxiosRequestConfig {
  interceptors?: MyInterceptors //扩展后的拦截器
  showLoading?: boolean //是否显示加载动画
}

 基于axios封装的类:

//封装一个axios的类,每次使用时生成一个新的实例,这样配置多种不同服务器请求的接口
import axios from 'axios'
//导入axios的  实例的类型
import type { AxiosInstance } from 'axios'
//导入扩展后的接口类型 和扩展后的请求参数类型
import type { MyInterceptors, MyRequestConfig } from './types'
//导入请求动画组件
import { ElLoading } from 'element-plus'
// 导入请求动画实例的类型,用于取消动画
import { LoadingInstance } from 'element-plus/lib/components/loading/src/loading'
//封装axios
class MyAxios {
  instance: AxiosInstance //实例
  interceptors?: MyInterceptors //拦截器
  loading?: LoadingInstance //加载动画
  showLoading?: boolean //是否显示请求的动画
  //config的类型改为加了自己扩展后的类型:AxiosRequestConfig--->MyRequestConfig,
  //上面会增加interceptors接口,支持同时传入多个拦截器,和接受是否显示动画的配置
  constructor(config: MyRequestConfig) {
    //每次调用instance都会产生一个新的实例,在新的实例上面配置新的baseurl等配置
    this.instance = axios.create(config)
    //保存一份传入的所有拦截器
    this.interceptors = config.interceptors
    //默认显示请求动画:showLoading默认为true
    this.showLoading = config.showLoading ?? true
    //使用实例身上的请求拦截器和响应拦截器的方法,把传入拦截器对象中的方法依次传入
    this.instance.interceptors.request.use(
      this.interceptors?.resquestInterceptors,
      this.interceptors?.resquestInterceptorsCatch
    )
    this.instance.interceptors.response.use(
      this.interceptors?.responseInterceptors,
      this.interceptors?.responseInterceptorsCatch
    )
    //但是有些拦截器配置每个实例都会需要,
    //如请求时的动画,需要全局配置,让每个实例中都存在,就直接使用axios上面的拦截器进行封装
    this.instance.interceptors.request.use(
      (config) => {
        console.log('全局拦截成功')
        //全局配置loading动画,拿下loading
        if (this.showLoading)
          this.loading = ElLoading.service({
            lock: true,
            text: '正在加载...',
            background: 'rgba(0,0,0,0.5)',
          })
        return config
      },
      (err) => {
        console.log('全局拦截失败')
        return err
      }
    )
    this.instance.interceptors.response.use(
      (res) => {
        setTimeout(() => {
          this.loading?.close()
        }, 1000)
        console.log('全局响应成功')
        const data = res.data
        if (data.returnCode == '-1001') {
          console.log('请求失败')
        } else {
          return data
        }
      },
      (err) => {
        console.log('全局响应失败')
        this.loading?.close() //移除加载动画
        if (err.response.status === 404) {
          console.log('404错误信息')
        }
        return err
      }
    )
  }

  //封装request请求
  //请求参数config要用自己扩展后的接口(MyRequestConfig),才支持传入对象形式的拦截器
  request<T>(config: MyRequestConfig): Promise<T> {
    return new Promise((resolve, resject) => {
      //还可以给单个请求配置拦截器
      if (config.interceptors?.resquestInterceptors) {
        //如果存在说明配置了单个请求的拦截器,就把转换后的config返回给config继续处理
        //config.interceptors.resquestInterceptors(config)返回的是一个处理过后的config
        config = config.interceptors.resquestInterceptors(config)
      }
      //请求动画默认false,如果showloading为false,就是关闭请求动画
      if (config.showLoading === false) {
        this.showLoading = config.showLoading
      }
      //使用axios自身的request发请求
      this.instance
        .request<any, T>(config)
        .then((res) => {
          //如果为真说明配置了单个请求的响应拦截器,就把转换后的res返回给res继续处理
          //config.interceptors.resquestInterceptors(res)返回的是一个处理过后的res
          if (config.interceptors?.responseInterceptors) {
            res = config.interceptors.responseInterceptors(res)
          }
          //让动画显示,即使上面不显示动画的请求完也设置,这样不影响后面的动画显示
          this.showLoading = true
          resolve(res)
        })
        .catch((err) => {
          this.showLoading = true
          resject(err)
        })
    })
  }
  //封装get请求,就是再get内部调request
  get<T>(config: MyRequestConfig): Promise<T> {
    return this.request<T>({ ...config, method: 'GET' })
  }
  //封装post请求,就是再post内部调request
  post<T>(config: MyRequestConfig): Promise<T> {
    return this.request<T>({ ...config, method: 'GET' })
  }
  //封装delete请求,就是再delete内部调request
  delete<T>(config: MyRequestConfig): Promise<T> {
    return this.request<T>({ ...config, method: 'GET' })
  }
  //封装patch请求,就是再patch内部调request
  patch<T>(config: MyRequestConfig): Promise<T> {
    return this.request<T>({ ...config, method: 'GET' })
  }
}
export default MyAxios

创建实例:

//配置MyAxios的实例并导出
import MyAxios from './request/index' //导入axios
import { BASE_URL, TIME_OUT } from '@/service/request/config' //导入环境变量
const myAxios = new MyAxios({
  baseURL: BASE_URL,
  timeout: TIME_OUT,
  //可选,单个实例的拦截器
  interceptors: {
    resquestInterceptors(config) {
      console.log('实例请求拦截成功')
      return config
    },
    resquestInterceptorsCatch(err) {
      console.log('实例请求拦截失败')
      return err
    },
    responseInterceptors(res) {
      console.log('实例响应拦截成功')
      return res
    },
    responseInterceptorsCatch(err) {
      console.log('实例请求拦截失败')
      return err
    },
  },
})
//导出封装的实例
export default myAxios

发送请求演示:

得到的返回值是我们传入接口的类型

 

在uni-app中封装axios,可以让你更方便地进行网络请求。axios是一个流行的基于Promise的HTTP客户端,可以在浏览器和Node.js中使用。 首先,你需要在uni-app项目中安装axios。在命令行中运行以下命令: ```shell npm install axios ``` 接下来,创建一个http.js文件,用于封装axios的配置和请求函数: ```javascript import axios from 'axios' // 创建axios实例 const instance = axios.create({ baseURL: 'http://example.com/api', // 设置请求的baseURL timeout: 5000, // 设置请求超时时间 }) // 请求拦截器 instance.interceptors.request.use( config => { // 在发送请求之前做些什么,比如添加token等 return config }, error => { // 对请求错误做些什么 return Promise.reject(error) } ) // 响应拦截器 instance.interceptors.response.use( response => { // 对响应数据做些什么 return response.data }, error => { // 对响应错误做些什么 return Promise.reject(error) } ) export default instance ``` 在上面的代码中,我们创建了一个axios实例,并设置了baseURL和timeout。然后,我们通过拦截器对请求进行处理,可以在请求发送前和响应返回后做一些额外的处理,比如添加token、处理错误等。 现在,你可以在项目的任何地方使用这个封装好的axios实例进行网络请求。例如: ```javascript import http from '@/utils/http' http.get('/users') .then(data => { console.log(data) }) .catch(err => { console.error(err) }) ``` 这样,你就可以在uni-app中使用封装好的axios进行网络请求了。当然,你还可以根据自己的需求对axios进行更多的配置和封装。希望对你有帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值