文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

vue3项目中封装axios的示例代码

2022-12-19 12:00

关注

目前前端最流行的网络请求库还是axios,所以对axios的封装很有必要,此次基于vue3+ts的环境下。

axios的基本使用

import axios from 'axios'
// console.log('adh')
axios.get('http://XXX.xxx.xxx.xxx:8000/home').then((res) => {
  console.log(res.data)
})

axios.get()会返回一个Promise对象,所以可以用.then获取返回的数据。

axios.all()方法

axios.all([
  axios.get('http://httpbin.org/get').then((res) => {
    console.log(res.data)
  }),
  axios.post('http://httpbin.org/post').then((res) => {
    console.log(res.data)
  })
])

axios一些基本配置

在axios中,有一些默认配置,它们是存在于axios.defaults中的,比如我们经常会用到的baseURL、timeout属性

axios.defaults.baseURL = 'http://httpbin.org'
axios.defaults.timeout = 10000

axios的拦截器

在平常的使用中,我们经常需要对axios请求进行拦截以处理一些特殊情况,如获取token、处理异常等,这时候我们就需要使用axios的拦截器()。

axios.interceptors.request.use(
  (config) => {
    return config
  },
  (error) => {
    return error
  }
)
axios.interceptors.response.use(
  (res) => {
    console.log(res.data)
  },
  (error) => {
    return error
  }
)

如上,axios.interceptors.request是对请求的拦截,此时可以为请求添加headers,添加token等操作,二axios.interceptors.response则是对请求的返回进行拦截,在此处我们可以统一返回的数据结构以及对错误进行一些统一的处理

封装axios-封装基础属性

首先,我们先确认一下基本思路,我们把主要的逻辑封装成一个类,然后编写一个出口文件,将该类导出,需要注意的是,往这个类中传入哪些参数,诚然,我们可以直接在类中定义诸如BASE_URL、timeout、interceptors等axios的属性或方法,但是为了今后的可适配性更高,我们应该尽量的把可配置的属性作为变量传入我们欲封装的类中,下面先进行一个基本的封装:

// 封装类
import axios from 'axios'
import { AxiosInstance, AxiosRequestConfig } from 'axios'
class ZWRequest {
  instance: AxiosInstance
  constructor(config: AxiosRequestConfig) {
    this.instance = axios.create(config)
  }

  request(config: AxiosRequestConfig): void {
    this.instance.request(config).then((res) => {
      console.log(res) // 此处能成功打印出结果代表成功
    })
  }
}
export default ZWRequest
// 出口文件index.ts
import ZWRequest from './request'
import { BASE_URL, timeout } from './request/config'

const zwRequest = new ZWRequest({
  baseURL: BASE_URL, // 配置参数
  timeout: timeout // 配置参数
})
export default zwRequest
// 在main.ts中测试
import ZWRequest from './service/index.ts'
ZWRequest.request({
  url: '/post',
  method: 'POST'
})

封装拦截器

上面的封装可以传入BASE_URL、timeout等一些基础属性,但是对于拦截器interceptors还是不能实现配置,所以下一步我们改造一下使其可以传入拦截器:

// 封装类
import axios from 'axios'
import { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'

// 自建一个用于匹配interceptors的类型
interface ZWRequestInterceptors {
  requestInterceptor?: (config: AxiosRequestConfig) => AxiosRequestConfig // 这是个函数类型
  requestErrorInterceptor?: (error: any) => any
  responseInterceptor?: (config: AxiosResponse) => AxiosResponse
  responseErrorInterceptor?: (error: any) => any
}

interface ZWRequestConfig extends AxiosRequestConfig {
  interceptors?: ZWRequestInterceptors
}
class ZWRequest {
  instance: AxiosInstance
  interceptors?: ZWRequestInterceptors
  constructor(config: ZWRequestConfig) {
    this.instance = axios.create(config)
    this.interceptors = config.interceptors
    this.instance.interceptors.request.use(
      this.interceptors?.requestInterceptor,
      this.interceptors?.requestErrorInterceptor
    )
    this.instance.interceptors.response.use(
      this.interceptors?.responseInterceptor,
      this.interceptors?.responseErrorInterceptor
    )
  }

  request(config: ZWRequestConfig): void {
    this.instance.request(config).then((res) => {
      console.log(res)
    })
  }
}
export default ZWRequest
// 出口函数index.ts

import ZWRequest from './request'
import { BASE_URL, timeout } from './request/config'

const zwRequest = new ZWRequest({
  baseURL: BASE_URL,
  timeout: timeout,
  interceptors: {
    requestInterceptor: (config) => {
      console.log('发送请求成功11', config)
      return config
    },
    responseInterceptor: (res) => {
      console.log('返回成功11', res)
      return res
    }
  }
})
const zwRequest2 = new ZWRequest({
  baseURL: BASE_URL,
  timeout: timeout,
  interceptors: {
    requestInterceptor: (config) => {
      console.log('发送请求成功22', config)
      return config
    },
    responseInterceptor: (res) => {
      console.log('返回成功22', res)
      return res
    }
  }
})
export default zwRequest
// main.ts中实验
ZWRequest.request({
  url: '/post',
  method: 'POST'
})
ZWRequest2.request({
  url: '/post',
  method: 'POST'
})

封装公用的拦截器

上面的封装中,拦截器是由每个实例传入的,但是有时候我们就是想所有的实例都拥有共同的拦截器,那么我们就需要在axios封装类里面添加共有的拦截器了(实例传入的拦截器也并不会被取消),只需要在axios封装类中添加以下代码即可实现全局的拦截:

this.instance.interceptors.request.use(
      (config) => {
        console.log('共有的请求时成功拦截')
        return config
      },
      (error) => {
        console.log('共有的请求时失败拦截')
        return error
      }
    )
this.instance.interceptors.response.use(
  (res) => {
    console.log('共有的返回时成功的拦截')
    return res
  },
  (error) => {
    console.log('共有的返回时失败的拦截')
    return error
  }
)

对单个请求传入拦截器

其实上面对拦截器的封装已经基本可以满足平时的开发需求了,但是如果你想更灵活些,比如每个请求都可以传入自己的拦截器,那么请往下看,如果我们需要再请求时传入拦截器,那么就需要看看我们是怎么调用的。目前,我们采用ZWRequest.request(config)的方式调用axios请求,很显然,在封装类中,config参数的类型是:AxiosRequestConfig,这个类型很显然不能传入拦截器参数。

request(config: AxiosRequestConfig): void {
   this.instance.request(config).then((res) => {
     console.log(res)
   })
 }

所以为了能够往request方法中传入拦截器参数,我们需要将AxiosRequestConfig类型化成我们上面新建立的类型ZWRequestConfig,这样就可以从单个请求处传入各自的拦截器了。

// 改造axios封装类中的request方法
request(config: ZWRequestConfig): void {
    // 对单独请求传来的拦截器进行处理
    if (config.interceptors?.requestInterceptor) {
      config = config.interceptors?.requestInterceptor(config)
    }
    this.instance.request(config).then((res) => {
      if (config.interceptors?.responseInterceptor) {
        res = config.interceptors?.responseInterceptor(res)
      }
      console.log(res)
    })
}
// 在main.ts中进行测试
ZWRequest.request({
  url: '/post',
  method: 'POST',
  interceptors: {
    requestInterceptor: (config) => {
      console.log('单独请求的请求成功拦截')
      return config
    },
    responseInterceptor: (res) => {
      console.log('单独请求的响应成功拦截')
      return res
    }
  }
})

可以正常打印,成功!

对request请求方法封装

上面其实已经对request请求进行了大部分的封装了,但是此时的各种返回还局限在类里面,我们在main.ts中是无法拿到的,那么想要拿到返回值,我们就需要进一步操作,其实就是利用promise将结果返回出来:


// 对request方法的改造
request<T>(config: ZWRequestConfig): Promise<T> {
  return new Promise((resolve, 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) => {
        // 每次请求返回后将showLoading的值改为默认值,以免被这次请求穿的配置影响下一次请求的加载动画显示
        this.showLoading = DEFAULT_LOADING
        if (config.interceptors?.responseInterceptor) {
          res = config.interceptors?.responseInterceptor(res)
        }
        resolve(res)
        console.log(res)
      })
      .catch((error) => {
        console.log(error)
        this.showLoading = DEFAULT_LOADING
        reject(error)
      })
  })
}
// 在main.ts中实验
interface dataType {
  data: any
  returnCode: string
  success: boolean
}
ZWRequest.request<dataType>({
  url: '/home/multidata',
  method: 'GET'
  // showLoading: false
}).then((res) => {
  console.log(res.data)
  console.log(res.returnCode)
  console.log(res.success)
})

由上可见,其实操作很简单,那么接下来即使利用已经写好的request方法来些各种常用的请求调用方法了,就不多做赘述了,代码如下:

get<T>(config: ZWRequestConfig): Promise<T> {
return this.request<T>({ ...config, method: 'GET' })
}
post<T>(config: ZWRequestConfig): Promise<T> {
  return this.request<T>({ ...config, method: 'POST' })
}
delete<T>(config: ZWRequestConfig): Promise<T> {
  return this.request<T>({ ...config, method: 'DELETE' })
}

以上就是本人对axios的全部封装,完毕!

到此这篇关于vue3项目中封装axios的文章就介绍到这了,更多相关vue3封装axios内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯