基于uniapp+vue3+ts的api请求封装,并可自定义拦截器

5 篇文章 0 订阅
4 篇文章 0 订阅
该代码段展示了如何在uni-app中创建一个网络请求类,实现了请求和响应的拦截器,用于处理请求前后的配置和数据转换。同时,提供了GET、POST、PUT和DELETE等HTTP方法的封装,并设置了默认配置和修改配置的方法。
摘要由CSDN通过智能技术生成

requestClass.ts

const config = Symbol('config')
const isCompleteURL = Symbol('isCompleteURL')
const requestBefore = Symbol('requestBefore')
const requestAfter = Symbol('requestAfter')

class requestClass {
  // 默认配置
  [config]: { baseURL?: string } & UniApp.RequestOptions = {
    baseURL: '',
    url: '',
    header: {
      'content-type': 'application/x-www-form-urlencoded',
    },
    method: 'GET',
    timeout: 3000,
    dataType: 'json',
    responseType: 'text'
  }

  // 拦截器
  interceptors = {
    request: (func: Fn) => {
      if (func) {
        requestClass[requestBefore] = func
      } else {
        requestClass[requestBefore] = (request) => request
      }
    },
    response: (func: Fn) => {
      if (func) {
        requestClass[requestAfter] = func
      } else {
        requestClass[requestAfter] = (response) => response
      }
    },
  }

  // 请求之前,是默认配置
  static [requestBefore](config: UniApp.RequestOptions) {
    return config
  }
  // 请求之后,默认配置发生改变的话
  static [requestAfter](response: any) {
    return response
  }
  // 判断url是否完整
  static [isCompleteURL](url: string) {
    return /(http|https):\/\/([\w.]+\/?)\S*/.test(url)
  }

  request(options: UniApp.RequestOptions & { baseURL?: string }) {
    options.baseURL = options.baseURL || this[config].baseURL
    options.dataType = options.dataType || this[config].dataType
    options.url = requestClass[isCompleteURL](options.url) ? options.url : (options.baseURL + options.url)
    options.data = options.data
    options.header = { ...options.header, ...this[config].header }
    options.method = options.method || this[config].method

    options = { ...options, ...requestClass[requestBefore](options) }

    return new Promise((resolve, reject) => {
      options.success = function (res) {
        resolve(requestClass[requestAfter](res))
      }
      options.fail = function (err) {
        reject(requestClass[requestAfter](err))
      }
      uni.request(options)
      // 中断请求实现方法
      // let obj: any = {}
      // obj[request.url] = uni.request(options)
      // abortRequest() {
      //   for (const key in obj) {
      //     if (Object.prototype.hasOwnProperty.call(obj, key)) {
      //       const element = obj[key];
      //       element.abort()
      //     }
      //   }
      // }
    })
  }

  get(url: string, data: any = {}, options: Recordable = {}) {
    return this.request({ ...options, url, data, method: 'GET' })
  }

  post(url: string, data: any = {}, options: Recordable = {}) {
    return this.request({ ...options, url, data, method: 'POST' })
  }

  put(url: string, data: any = {}, options: Recordable = {}) {
    return this.request({ ...options, url, data, method: 'PUT' })
  }

  delete(url: string, data: any = {}, options: Recordable = {}) {
    return this.request({ ...options, url, data, method: 'DELETE' })
  }

  getConfig() {
    return this[config]
  }
  
  // 修改默认配置的一个方法,可以修改请求地址,请求方式等等..
  setConfig(func: Fn) {
    this[config] = func(this[config])
  }
}

export default requestClass

index.ts

import requestClass from './requestClass'
import { baseUrl } from '@/config'
import qs from 'qs'

const Request = new requestClass()

// 请求拦截器
Request.interceptors.request((request: any) => {
  if (request.header.contentType) {
    request.header['content-type'] = request.header.contentType
    delete request.header.contentType
  }
  if (request.method === 'GET') {
    request.data = qs.stringify(request.data)
    request.url = request.url + '?' + request.data
  }
  return request
})

// 响应拦截器
Request.interceptors.response((response: any) => {
  const token = uni.getStorageSync('token')
  // if (response.data.code === 403) {
  //   uni.showToast({
  //     title: token ? '请重新登录' : '请先登录',
  //     icon: 'none',
  //     duration: 2000,
  //   })
  //   uni.removeStorageSync('token')
  //   uni.removeStorageSync('userInfo')
  // }
  return response
})

// 设置默认配置
Request.setConfig((config: any) => {
  config.baseURL = baseUrl
  if (uni.getStorageSync('token')) {
    config.header['Authorization'] = 'Bearer ' + uni.getStorageSync('token')
  }
  return config
})

export default Request

使用方法

import service from '@/service/index'

// json形式
const options = {
  header: { contentType: 'application/json' }
}

/**
 * @method 测试接口
 */
export function testGet(data :any) {
  return service.get('/testGet', data)
}

export function testPost(data :any) {
  return service.post('/testPost', data, options)
}

export function testPut(data :any) {
  return service.post('/testPut', data)
}

export function testDelete(data :any) {
  return service.delete('/testDelete', data)
}

global.d.ts

type Nullable<T> = T | null
type Recordable<T = any> = Record<string, T>
type ReadonlyRecordable<T = any> = Readonly<Record<string, T>>
type Indexable<T = any> = Record<string, T>
type DeepPartial<T> = {
  [P in keyof T]?: DeepPartial<T[P]>
}
type TimeoutHandle = ReturnType<typeof setTimeout>
type IntervalHandle = ReturnType<typeof setInterval>

interface Fn<T = any, R = T> {
  (...arg: T[]): R
}
interface PromiseFn<T = any, R = T> {
  (...arg: T[]): Promise<R>
}

interface initBody{
 [key: string]: unknown
}

declare const wx: any
  • 7
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值