首页 > 其他分享 >VUE3 AXIOS 封装

VUE3 AXIOS 封装

时间:2023-01-09 23:13:16浏览次数:40  
标签:AXIOS 封装 url data VUE3 error config response pending

网上找了很多AXIOS的封装但是都不是很满意,后来参考其他人的实现做了改动后特分享出来

http.ts 文件封装

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

const service = axios.create({
  baseURL: import.meta.env.VITE_HOST,
  headers: {
    'Content-Type': 'application/json'
  },
  // 是否跨站点访问控制请求
  withCredentials: false,
  timeout: 30000,
  transformRequest: [(data, headers) => {
    //Content-Type:"multipart/form-data"
    if (headers["Content-Type"] == "application/json") {
      data = JSON.stringify(data)
    }
    return data
  }],
  validateStatus() {
    // 使用async-await,处理reject情况较为繁琐,所以全部返回resolve,在业务代码中处理异常
    return true
  },
  transformResponse: [(data) => {
    if (typeof data === 'string' && data.startsWith('{')) {
      data = JSON.parse(data)
    }
    return data
  }]
})

// 声明一个 Map 用于存储每个请求的标识 和 取消函数
const pending = new Map()
/**
 * 添加请求
 * @param {Object} config 
 */
const addPending = (config: AxiosRequestConfig) => {
  const url = [
    config.method,
    config.url,
    config.params,
    config.data
  ].join('&')
  config.cancelToken = config.cancelToken || new axios.CancelToken(cancel => {
    if (!pending.has(url)) { // 如果 pending 中不存在当前请求,则添加进去
      pending.set(url, cancel)
    }
  })
}

/**
 * 移除请求
 * @param {Object} config 
 */
const removePending = (config: AxiosRequestConfig) => {
  const url = [
    config.method,
    config.url,
    config.params,
    config.data
  ].join('&')
  if (pending.has(url)) { // 如果在 pending 中存在当前请求标识,需要取消当前请求,并且移除
    const cancel = pending.get(url)
    cancel(url)
    pending.delete(url)
  }
}

/**
 * 清空 pending 中的请求(在路由跳转时调用)
 */
export const clearPending = () => {
  for (const [url, cancel] of pending) {
    cancel(url)
  }
  pending.clear()
}

/**
 * 请求拦截器
 */
service.interceptors.request.use((config: AxiosRequestConfig) => {
  removePending(config) // 在请求开始前,对之前的请求做检查取消操作
  addPending(config) // 将当前请求添加到 pending 中
  let token = localStorage.getItem('__TOKEN__')
  if (token && config.headers) {
    // 服务端 Bearer JWT 要求 Bearer前缀
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config
}, 
(error) => {
  // 错误抛到业务代码
  error.data = {}
  error.data.msg = '服务器异常,请联系管理员!'
  return Promise.resolve(error)
})

/**
 * 响应拦截器
 *  */ 
service.interceptors.response.use(
  (response: AxiosResponse) => {

    removePending(response.config); // 在请求结束后,移除本次请求
    const status = response.status
    let msg = ''
    if (status < 200 || status >= 300) {
      // 处理http错误,抛到业务代码
      // msg = showStatus(status)
      if (typeof response.data === 'string') {
        response.data = { msg }
      } else {
        response.data.msg = msg
      }
    }

    // 续签TOKEN
    if (response.headers && response.headers.authorization) {
      localStorage.setItem('__TOKEN__', response.headers.authorization)

    }

    return response
  },
  (error) => {
    if (axios.isCancel(error)) {
      console.log('repeated request: ' + error.message)
    } else {
      // handle error code
      // 错误抛到业务代码
      error.data = {}
      error.data.msg = '请求超时或服务器异常,请检查网络或联系管理员!'
      // ElMessage.error(error.data.msg)
    }
    return Promise.reject(error)
  })

export default service


 

Service封装: MediaService.ts

import Axios from 'http';
import type { HttpResponse } from './HttpResponse';
import type { AxiosProgressEvent } from 'axios';


export class MediaService {

    /**
     * 上传文件
     */
    static async UploadFile(data: any): Promise<HttpResponse<any>> {

        let fileName = data.file.name;

        let formData = new FormData();
        formData.append('file', data.file, fileName)

        return Axios('http://localhost:29322/api/...', {
            method: 'post',
            headers: {
                'Content-Type': 'multipart/form-data'
            },
            responseType: 'json',
            data: formData,
            onUploadProgress(args: AxiosProgressEvent) {
                if (args.total) {
                    data.onProgress({ percent: Math.round((args.loaded / args.total) * 100) }, data.file);
                }
            }
        });
    }

    static async AddLibrary(data: any): Promise<HttpResponse<any>> {
        return Axios('http://localhost:29322/api/...', {
            method: 'post',
            responseType: 'json',
            data: data            
        });
    }
}

 

VUE页面调用参考

import { MediaService } from 'MediaService';


MediaService.AddLibrary(formState).then(res => {
   // ...
});

MediaService.UploadFile(data).then(res => {
     // ...
});

 

其他相关文件  HttpResponse.ts

export interface HttpResponse<T> {
  status: number
  statusText: string
  data: {
    code: number
    message: string
    data:T
    [key: string]: any
  }
}

 

标签:AXIOS,封装,url,data,VUE3,error,config,response,pending
From: https://www.cnblogs.com/moonwebmast/p/17038801.html

相关文章

  • mybatis接口方法中可以接收各种各样的参数,mybatis底层对于这些参数进行不同的封装处理
    mybatis底层将传进来的参数封装成map集合,每个集合中会有对应的参数值argx,因此假如不使用注解,会出现下面的错误,提醒找不到该参数###Errorqueryingdatabase.Cause:org......
  • 关于MyBatis查询属性封装到对象,对象为null的情况源码分析
    源码分析在DefaultResultSetHandler类中getRowValue方法创建映射类相应的对象,如果为列匹配到的值标识foundValues是false,表示没有为对象中任何一个字段映射到一个值,则......
  • 安卓苹果APP在线封装打包制作过程-H5手机网站转APP网站工具-免签封装绿标
    Webapp打包就是在一台机器上打包一个文件包或者程序包。在服务器端,应用软件与服务器端程序是分开的。在前端,应用软件通过浏览器安装到移动设备上。因此,移动应用程序应该与网......
  • 【首页】文字封装开发
    一、【首页】文字封装开发1.1在components/common目录中创建了Card.vue组件文件1.2在pages/index/index.vue中引入Card组件1.3Card组件是卡片完成效果为复用的文字1......
  • 多项式半家桶,但是未封装
    多项式乘法逆题意:给定\(n-1\)次多项式\(F(x)\),求多项式\(G(x)\),使得\(F(x)G(x)\equiv1\pmod{x^n}\)思路:设:\[F(x)g(x)\equiv1\pmod{x^m}\\\\\F......
  • vue3 中动态绑定 img src 问题
    vite 官方默认的配置,如果资源文件在assets文件夹打包后会把图片名加上hash值,但是直接通过:src="imgSrc"方式引入并不会在打包的时候解析,导致开发环境可以正常引入,打包后......
  • vue3 之生成二维码
    使用QPCode生成二维码前提:vue3+ts项目安装QPCodenpminstallqrcodejs2-fixes引入importQRCodefrom'qrcodejs2-fixes';页面部分<divclass="login-scan-contain......
  • vue3之 websocket
    前提:vue3+ts项目使用websocket一、在utils文件夹中创建websocket.ts文件/***websocket*///constwsUrl=`ws://`+window.location.host+`/emergency/webSocket......
  • Ajax(Fetch&Axios)
    传统服务器传统服务器的结构是基于MVC模式Model--数据模型View--视图,用来呈现Controller--控制器,复杂加载数据并选择视图来呈现数据传统的服务器是直接为客户端......
  • JSON to TS 转化 Axios 请求类型约束
    JSONtoTS扩展插件的使用作用场景作用是快速转化React+TS的Axios拿回数据的类型约束定义 步骤一.获取数据当页面中发起请求成功,获取到接口所携带的数据时,cons......