vue3+ts封装axios请求

本文主要介绍了vue3和typescript+vite实际开发中对axios的请求封装

1.目录划分

在我们实际开发中,通常会对不同功能进行不同的目录结构划分

例如:网路请求我们通常会封装到api目录下面,然后里面分模块modules以及类型types、axios配置等

2.请求配置

axios请求时,一般会配置baseUrl,timeout等,我们可以把这些固定的配置项放到config.ts文件里,然后导出

let BASE_URL = ''
const TIME_OUT = 10000

if (process.env.NODE_ENV === 'development') {
  BASE_URL = 'XXXXXXXXX'
} else if (process.env.NODE_ENV === 'production') {
  BASE_URL = 'XXXXXXXXX'
}

const AXIOS_BASE_CONFIG = {
  baseURL: BASE_URL,
  timeOut: TIME_OUT,
  heard: {
    'Content-Type': 'application/json; charset=utf-8',
  },
}

export { BASE_URL, AXIOS_BASE_CONFIG }

3.axios封装

import axios from 'axios'
import qs from 'qs'
import { AXIOS_BASE_CONFIG } from './config'

import type { AxiosRequestConfig, AxiosResponse, AxiosInstance } from 'axios'

import { message } from 'ant-design-vue'

import * as TYPES from '@/types/mutation-type'
import useStorage from '@/hooks/useStorage'

type axiosResponse<T = any> = {
  Message: string
  ResultCode: number
  Success: boolean
  Tag: T
  TotalRecord: string | number
}

const { getStorage } = useStorage()

const handleError = (error: any) => {
  const {
    data: { Message },
  } = error.response
  message.destroy()
  message.error(Message ? Message : '请求失败,请重新刷新页面')
  return Promise.reject(error)
}

class Request {
  private instance: AxiosInstance
  constructor(config: AxiosRequestConfig = {}) {
    this.instance = axios.create({ ...AXIOS_BASE_CONFIG, ...config })
    this.initInstance()
  }

  /**
   * @method 初始化拦截器
   */
  private initInstance() {
    /**
     * @method 请求拦截器
     */
    this.instance.interceptors.request.use((config: AxiosRequestConfig) => {
      const _token = getStorage('session', TYPES.ASSESS_TOKEN)
      if (_token) {
        config.headers!.common['Authorization'] = _token
      }
      if (['GET', 'get'].includes(config.method!)) {
        config.url += '?' + qs.stringify(config.data ?? '')
      }
      return config
    }, handleError)

    /**
     * @method 响应拦截器
     */
    this.instance.interceptors.response.use((response: AxiosResponse<axiosResponse>) => {
      if (!response.data.Success) {
        message.error(response.data.Message ?? '系统异常')
        if ([403, 505].includes(response.data.ResultCode)) {
          setTimeout(() => {
            window.location.replace(window.location.origin)
          }, 500)
        }
        return Promise.reject(response.data)
      }

      return Promise.resolve(response.data)
    }, handleError)
  }

  /**
   * @method 请求
   * @param config 请求配置项
   */
  private request<D = any>(config: AxiosRequestConfig) {
    return new Promise<axiosResponse<D>>(async (resolve, reject) => {
      try {
        const res = await this.instance.request<axiosResponse<D>, axiosResponse<D>>(config)
        resolve(res)
      } catch (error) {
        console.log('error', error)
        reject(error)
      }
    })
  }

  /**
   * @method GET请求
   * @param config 请求配置项
   */
  public GET<R>(config: AxiosRequestConfig) {
    return this.request<R>({ ...config, method: 'GET' })
  }

  /**
   * @method POST请求
   * @param config 请求配置项
   */
  public POST<R>(config: AxiosRequestConfig) {
    return this.request<R>({ ...config, method: 'POST' })
  }

  /**
   * @method PUT请求
   * @param config 请求配置项
   */
  public PUT<R>(config: AxiosRequestConfig) {
    return this.request<R>({ ...config, method: 'PUT' })
  }

  /**
   * @method DELETE请求
   * @param config 请求配置项
   */
  public DELETE<R>(config: AxiosRequestConfig) {
    return this.request<R>({ ...config, method: 'DELETE' })
  }
}

export default Request

4.使用

import request from '@/service'
const http = new request()
type dictionaryType = {
  name: string
  code: string
  id: string | number
  nameAdCode?: string
  nameAndCode?: string
  value?: string
  label?: string
}

enum roadWayApiEnum {
  tunnelFindDropDown = 'XXX/XXXXX/XXXXX'
}

export const tunnelFindDropDown = (data: any) => http .POST<dictionaryType[]>({ url: roadWayApiEnum.tunnelFindDropDown, data })  
import { regionFindDropDown } from '@/service/modules/roadWay_api'

async function initRegionOption() {
  const { Tag, Success } = await regionFindDropDown({ id: formState.value.id})
  if (Success) {
    Tag.forEach((item) => {
      item.nameAdCode = `【${item.code}】${item.name}`
    })
    wholeOptions.regionOptions = Tag

  }
}

按照我们这样封装后,在调用请求时传入Tag的泛型,我们解构出来的Tag直接就是这个类型

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值