iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >如何使用Typescript封装axios
  • 622
分享到

如何使用Typescript封装axios

2023-07-02 16:07:39 622人浏览 安东尼
摘要

本文小编为大家详细介绍“如何使用typescript封装axiOS”,内容详细,步骤清晰,细节处理妥当,希望这篇“如何使用Typescript封装axios”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。基础封装首

本文小编为大家详细介绍“如何使用typescript封装axiOS”,内容详细,步骤清晰,细节处理妥当,希望这篇“如何使用Typescript封装axios”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

    基础封装

    首先我们实现一个最基本的版本,实例代码如下:

    // index.tsimport axios from 'axios'import type { AxiosInstance, AxiosRequestConfig } from 'axios'class Request {  // axios 实例  instance: AxiosInstance  constructor(config: AxiosRequestConfig) {    this.instance = axios.create(config)  }  request(config: AxiosRequestConfig) {    return this.instance.request(config)  }}export default Request

    这里将其封装为一个类,而不是一个函数的原因是因为类可以创建多个实例,适用范围更广,封装性更强一些。

    拦截器封装

    首先我们封装一下拦截器,这个拦截器分为三种:

    • 类拦截器

    • 实例拦截器

    • 接口拦截器

    接下来我们就分别实现这三个拦截器。

    类拦截器

    类拦截器比较容易实现,只需要在类中对axios.create()创建的实例调用interceptors下的两个拦截器即可,实例代码如下:

    // index.tsconstructor(config: AxiosRequestConfig) {  this.instance = axios.create(config)  this.instance.interceptors.request.use(    (res: AxiosRequestConfig) => {      console.log('全局请求拦截器')      return res    },    (err: any) => err,  )  this.instance.interceptors.response.use(    // 因为我们接口的数据都在res.data下,所以我们直接返回res.data    (res: AxiosResponse) => {      console.log('全局响应拦截器')      return res.data    },    (err: any) => err,  )}

    我们在这里对响应拦截器做了一个简单的处理,就是将请求结果中的.data进行返回,因为我们对接口请求的数据主要是存在在.data中,跟data同级的属性我们基本是不需要的。

    实例拦截器

    实例拦截器是为了保证封装的灵活性,因为每一个实例中的拦截后处理的操作可能是不一样的,所以在定义实例时,允许我们传入拦截器。

    首先我们定义一下interface,方便类型提示,代码如下:

    // types.tsimport type { AxiosRequestConfig, AxiosResponse } from 'axios'export interface RequestInterceptors {  // 请求拦截  requestInterceptors?: (config: AxiosRequestConfig) => AxiosRequestConfig  requestInterceptorsCatch?: (err: any) => any  // 响应拦截  responseInterceptors?: (config: AxiosResponse) => AxiosResponse  responseInterceptorsCatch?: (err: any) => any}// 自定义传入的参数export interface RequestConfig extends AxiosRequestConfig {  interceptors?: RequestInterceptors}

    定义好基础的拦截器后,我们需要改造我们传入的参数的类型,因为axios提供的AxiosRequestConfig是不允许我们传入拦截器的,所以说我们自定义了RequestConfig,让其继承与AxiosRequestConfig

    剩余部分的代码也比较简单,如下所示:

    // index.tsimport axios, { AxiosResponse } from 'axios'import type { AxiosInstance, AxiosRequestConfig } from 'axios'import type { RequestConfig, RequestInterceptors } from './types'class Request {  // axios 实例  instance: AxiosInstance  // 拦截器对象  interceptorsObj?: RequestInterceptors  constructor(config: RequestConfig) {    this.instance = axios.create(config)    this.interceptorsObj = config.interceptors    this.instance.interceptors.request.use(      (res: AxiosRequestConfig) => {        console.log('全局请求拦截器')        return res      },      (err: any) => err,    )    // 使用实例拦截器    this.instance.interceptors.request.use(      this.interceptorsObj?.requestInterceptors,      this.interceptorsObj?.requestInterceptorsCatch,    )    this.instance.interceptors.response.use(      this.interceptorsObj?.responseInterceptors,      this.interceptorsObj?.responseInterceptorsCatch,    )    // 全局响应拦截器保证最后执行    this.instance.interceptors.response.use(      // 因为我们接口的数据都在res.data下,所以我们直接返回res.data      (res: AxiosResponse) => {        console.log('全局响应拦截器')        return res.data      },      (err: any) => err,    )  }}

    我们的拦截器的执行顺序为实例请求→类请求→实例响应→类响应;这样我们就可以在实例拦截上做出一些不同的拦截,

    接口拦截

    现在我们对单一接口进行拦截操作,首先我们将AxiosRequestConfig类型修改为RequestConfig允许传递拦截器;

    然后我们在类拦截器中将接口请求的数据进行了返回,也就是说在request()方法中得到的类型就不是AxiosResponse类型了。

    我们查看axios的index.d.ts中,对request()方法的类型定义如下:

    // type.tsrequest<T = any, R = AxiosResponse<T>, D = any>(config: AxiosRequestConfig<D>): Promise<R>;

    也就是说它允许我们传递类型,从而改变request()方法的返回值类型,我们的代码如下:

    // index.tsrequest<T>(config: RequestConfig): Promise<T> {  return new Promise((resolve, reject) => {    // 如果我们为单个请求设置拦截器,这里使用单个请求的拦截器    if (config.interceptors?.requestInterceptors) {      config = config.interceptors.requestInterceptors(config)    }    this.instance      .request<any, T>(config)      .then(res => {        // 如果我们为单个响应设置拦截器,这里使用单个响应的拦截器        if (config.interceptors?.responseInterceptors) {          res = config.interceptors.responseInterceptors<T>(res)        }        resolve(res)      })      .catch((err: any) => {        reject(err)      })  })}

    这里还存在一个细节,就是我们在拦截器接受的类型一直是AxiosResponse类型,而在类拦截器中已经将返回的类型改变,所以说我们需要为拦截器传递一个泛型,从而使用这种变化,修改types.ts中的代码,示例如下:

    // index.tsexport interface RequestInterceptors {  // 请求拦截  requestInterceptors?: (config: AxiosRequestConfig) => AxiosRequestConfig  requestInterceptorsCatch?: (err: any) => any  // 响应拦截  responseInterceptors?: <T = AxiosResponse>(config: T) => T  responseInterceptorsCatch?: (err: any) => any}

    请求接口拦截是最前执行,而响应拦截是最后执行。

    封装请求方法

    现在我们就来封装一个请求方法,首先是类进行实例化示例代码如下:

    // index.tsimport Request from './request'const request = new Request({  baseURL: import.meta.env.BASE_URL,  timeout: 1000 * 60 * 5,  interceptors: {    // 请求拦截器    requestInterceptors: config => {      console.log('实例请求拦截器')      return config    },    // 响应拦截器    responseInterceptors: result => {      console.log('实例响应拦截器')      return result    },  },})

    然后我们封装一个请求方法, 来发送网络请求,代码如下:

    // src/server/index.tsimport Request from './request'import type { RequestConfig } from './request/types'interface YWZRequestConfig<T> extends RequestConfig {  data?: T}interface YWZResponse<T> {  code: number  message: string  data: T}const ywzRequest = <D, T = any>(config: YWZRequestConfig<D>) => {  const { method = 'GET' } = config  if (method === 'get' || method === 'GET') {    config.params = config.data  }  return request.request<YWZResponse<T>>(config)}export default ywzRequest

    该请求方式默认为GET,且一直用data作为参数;

    取消请求

    应评论区@Pic@Michaelee@Alone_Error的建议,这里增加了一个取消请求;关于什么是取消请求可以参考官方文档。

    准备工作

    我们需要将所有请求的取消方法保存到一个集合(这里我用的数组,也可以使用Map)中,然后根据具体需要去调用这个集合中的某个取消请求方法。

    首先定义两个集合,示例代码如下:

    // index.tsimport type {  RequestConfig,  RequestInterceptors,  CancelRequestSource,} from './types'class Request {    cancelRequestSourceList?: CancelRequestSource[]    requestUrlList?: string[]  constructor(config: RequestConfig) {    // 数据初始化    this.requestUrlList = []    this.cancelRequestSourceList = []  }}

    这里用的CancelRequestSource接口,我们去定义一下:

    // type.tsexport interface CancelRequestSource {  [index: string]: () => void}

    这里的key是不固定的,因为我们使用urlkey,只有在使用的时候才知道url,所以这里使用这种语法。

    取消请求方法的添加与删除

    首先我们改造一下request()方法,它需要完成两个工作,一个就是在请求之前将url和取消请求方法push到我们前面定义的两个属性中,然后在请求完毕后(不管是失败还是成功)都将其进行删除,实现代码如下:

    // index.tsrequest<T>(config: RequestConfig): Promise<T> {  return new Promise((resolve, reject) => {    // 如果我们为单个请求设置拦截器,这里使用单个请求的拦截器    if (config.interceptors?.requestInterceptors) {      config = config.interceptors.requestInterceptors(config)    }    const url = config.url    // url存在保存取消请求方法和当前请求url    if (url) {      this.requestUrlList?.push(url)      config.cancelToken = new axios.CancelToken(c => {        this.cancelRequestSourceList?.push({          [url]: c,        })      })    }    this.instance      .request<any, T>(config)      .then(res => {        // 如果我们为单个响应设置拦截器,这里使用单个响应的拦截器        if (config.interceptors?.responseInterceptors) {          res = config.interceptors.responseInterceptors<T>(res)        }        resolve(res)      })      .catch((err: any) => {        reject(err)      })      .finally(() => {        url && this.delUrl(url)      })  })}

    这里我们将删除操作进行了抽离,将其封装为一个私有方法,示例代码如下:

    // index.tsprivate getSourceIndex(url: string): number {  return this.cancelRequestSourceList?.findIndex(    (item: CancelRequestSource) => {      return Object.keys(item)[0] === url    },  ) as number}private delUrl(url: string) {  const urlIndex = this.requestUrlList?.findIndex(u => u === url)  const sourceIndex = this.getSourceIndex(url)  // 删除url和cancel方法  urlIndex !== -1 && this.requestUrlList?.splice(urlIndex as number, 1)  sourceIndex !== -1 &&    this.cancelRequestSourceList?.splice(sourceIndex as number, 1)}

    取消请求方法

    现在我们就可以封装取消请求和取消全部请求了,我们先来封装一下取消全部请求吧,这个比较简单,只需要调用this.cancelRequestSourceList中的所有方法即可,实现代码如下:

    // index.ts// 取消全部请求cancelAllRequest() {  this.cancelRequestSourceList?.forEach(source => {    const key = Object.keys(source)[0]    source[key]()  })}

    现在我们封装一下取消请求,因为它可以取消一个和多个,那它的参数就是url,或者包含多个URL的数组,然后根据传值的不同去执行不同的操作,实现代码如下:

    // index.ts// 取消请求cancelRequest(url: string | string[]) {  if (typeof url === 'string') {    // 取消单个请求    const sourceIndex = this.getSourceIndex(url)    sourceIndex >= 0 && this.cancelRequestSourceList?.[sourceIndex][url]()  } else {    // 存在多个需要取消请求的地址    url.forEach(u => {      const sourceIndex = this.getSourceIndex(u)      sourceIndex >= 0 && this.cancelRequestSourceList?.[sourceIndex][u]()    })  }}

    测试

    测试请求方法

    现在我们就来测试一下这个请求方法,这里我们使用www.apishop.net/提供的免费API进行测试,测试代码如下:

    <script setup lang="ts">// app.Vueimport request from './service'import { onMounted } from 'vue'interface Req {  apiKey: string  area?: string  areaiD?: string}interface Res {  area: string  areaCode: string  areaid: string  dayList: any[]}const get15DaysWeatherByArea = (data: Req) => {  return request<Req, Res>({    url: '/api/common/weather/get15DaysWeatherByArea',    method: 'GET',    data,    interceptors: {      requestInterceptors(res) {        console.log('接口请求拦截')        return res      },      responseInterceptors(result) {        console.log('接口响应拦截')        return result      },    },  })}onMounted(async () => {  const res = await get15DaysWeatherByArea({    apiKey: import.meta.env.VITE_APP_KEY,    area: '北京市',  })  console.log(res.result.dayList)})</script>

    如果在实际开发中可以将这些代码分别抽离。

    上面的代码在命令中输出

    接口请求拦截
    实例请求拦截器
    全局请求拦截器
    实例响应拦截器
    全局响应拦截器
    接口响应拦截
    [{&hellip;}, {&hellip;}, {&hellip;}, {&hellip;}, {&hellip;}, {&hellip;}, {&hellip;}, {&hellip;}, {&hellip;}, {&hellip;}, {&hellip;}, {&hellip;}, {&hellip;}, {&hellip;}, {&hellip;}]

    测试取消请求

    首先我们在.server/index.ts中对取消请求方法进行导出,实现代码如下:

    // 取消请求export const cancelRequest = (url: string | string[]) => {  return request.cancelRequest(url)}// 取消全部请求export const cancelAllRequest = () => {  return request.cancelAllRequest()}

    然后我们在app.vue中对其进行引用,实现代码如下:

    <template>  <el-button    @click="cancelRequest('/api/common/weather/get15DaysWeatherByArea')"    >取消请求</el-button  >  <el-button @click="cancelAllRequest">取消全部请求</el-button>  <router-view></router-view></template><script setup lang="ts">import request, { cancelRequest, cancelAllRequest } from './service'</script>

    发送请求后,点击按钮即可实现对应的功能

    读到这里,这篇“如何使用Typescript封装axios”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网精选频道。

    --结束END--

    本文标题: 如何使用Typescript封装axios

    本文链接: https://www.lsjlt.com/news/343071.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • 如何使用Typescript封装axios
      本文小编为大家详细介绍“如何使用Typescript封装axios”,内容详细,步骤清晰,细节处理妥当,希望这篇“如何使用Typescript封装axios”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。基础封装首...
      99+
      2023-07-02
    • 项目中使用Typescript封装axios
      目录写在前面基础封装拦截器封装类拦截器实例拦截器接口拦截封装请求方法取消请求准备工作取消请求方法的添加与删除取消请求方法测试测试请求方法测试取消请求写在最后写在前面 虽然说Fetch...
      99+
      2024-04-02
    • TypeScript利用TS封装Axios实战
      目录简介Axios几个常用类型AxiosRequestConfigAxiosInstanceAxiosStaticAxiosResponseAxiosError基础封装拦截器封装常用...
      99+
      2024-04-02
    • Vue3中使用typescript封装axios的实例详解
      这个axios封装,因为是用在vue3的demo里面的,为了方便,在vue3的配置里面按需加载element-plus 封装axios http.ts import axios,...
      99+
      2024-04-02
    • vue3 typescript封装axios过程示例
      目录1.目录层级2.request层2.1请求主体2.2拦截器2.3 封装请求方法3.api层3.1细分功能模块3.2api层主体4.service层5.将api层请求挂载到全局中6...
      99+
      2022-11-13
      vue3 typescript封装axio typescript封装axio
    • vue中如何使用axios和封装
      这篇文章给大家分享的是有关vue中如何使用axios和封装的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。vue官方推荐使用 axios发送请求首先上需求1.需要封装全局调用2.返...
      99+
      2024-04-02
    • Vue封装如何axios
      这篇文章主要介绍“Vue封装如何axios”,在日常操作中,相信很多人在Vue封装如何axios问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Vue封装如何axios”的疑惑有所帮助!接下来,请跟着小编一起来...
      99+
      2023-07-05
    • ts如何封装axios
      本篇内容主要讲解“ts如何封装axios”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“ts如何封装axios”吧!什么样封装才是最合理的别再用 promise 包了,好吗?看了一下,很多人封装 ...
      99+
      2023-07-05
    • vue如何封装axios
      今天小编给大家分享一下vue如何封装axios的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。vue封装axios可以提高代码...
      99+
      2023-07-04
    • vue3如何封装axios
      本文小编为大家详细介绍“vue3如何封装axios”,内容详细,步骤清晰,细节处理妥当,希望这篇“vue3如何封装axios”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。简介axios是一个基于promise的网...
      99+
      2023-07-02
    • Typescript 封装 Axios拦截器方法实例
      目录引言创建 classaxios.create([config])封装 request(config)通用方法封装-拦截器(单个实例独享)扩展 Http 自定义拦截器封装-拦截器(...
      99+
      2024-04-02
    • 如何用vue封装axios请求
      其实vue封装axios是很简单的 首先 在src路径下建http文件夹 并且创建api.js env.js request.js 这三个文件 env.js文件 这个文件主要就是封...
      99+
      2024-04-02
    • Vue如何二次封装axios为插件使用
      这篇文章给大家分享的是有关Vue如何二次封装axios为插件使用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。vuejs2.0 已经不再维护 vue-resource,vuejs...
      99+
      2024-04-02
    • 如何在vue中封装axios
      本篇文章为大家展示了如何在vue中封装axios,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。基础版第一步:配置axios首先,创建一个Service.js,这里面存放的时axios的配置以及拦截器...
      99+
      2023-06-15
    • vue如何封装axios请求
      这篇文章主要介绍“vue如何封装axios请求”,在日常操作中,相信很多人在vue如何封装axios请求问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”vue如何封装axios请求”的疑惑有所帮助!接下来,请跟...
      99+
      2023-07-04
    • 如何封装一个好用的axios
      这篇文章主要介绍了如何封装一个好用的axios的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇如何封装一个好用的axios文章都会有所收获,下面我们一起来看看吧。通用能力列一下我想要这个通用请求能达到什么样的效果...
      99+
      2023-07-02
    • Vue前端如何对axios的封装和使用
      这篇文章将为大家详细讲解有关Vue前端如何对axios的封装和使用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Axios 是一个基于 promise 的 HTTP 库。...
      99+
      2024-04-02
    • Vue3+TypeScript封装axios并进行请求调用的实现
      不是吧,不是吧,原来真的有人都2021年了,连TypeScript都没听说过吧?在项目中使用TypeScript虽然短期内会增加一些开发成本,但是对于其需要长期维护的项目,TypeS...
      99+
      2024-04-02
    • 如何使用TS对axios的进行简单封装
      目录1.安装axios2.在合适路径下新建request.ts(名称可随意),例如可以在项目的src下创建utils文件夹创建request.ts3.导入axios并创建axios实...
      99+
      2022-11-13
      ts axios简单封装 ts封装axios
    • 如何在vue项目中使用封装后的axios
      这篇文章给大家介绍如何在vue项目中使用封装后的axios,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。为什么要使用VueVue是一款友好的、多用途且高性能的JavaScript框架,使用vue可以创建可维护性和可测试...
      99+
      2023-06-06
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作