高效封装Axios,提高开发生产力

217 阅读1分钟

接口按功能分类

一个项目中肯定存在多个不同的功能,各个功能会有对应的接口,为了更方便管理,对项目的接口进行分类导出,后续需要对对应功能模块的接口进行修改或者查找会比较方便

声明一个metaData功能的接口文件,将属于该功能下的接口都放到一起,然后抛出

// service/mapping/metaApi
const metaApi = {
  'meta-api':{
    url:`${service}/meta/index`,
    type:'get'
  },
  'meta-api-detail':{
    url:`${service}/meta/detail`,
    type:'get'
  },
  'meta-api-create':{
    url:`${service}/meta/create`,
    type:'post'
  }
}
export default metaApi

整合统一各个功能接口

上面只是一个接口模块,接着需要对接口模块进行统一整合,放到一个index文件中,将所有的接口抛出,而不是用到哪个功能引入哪个模块接口。

//service/mapping/index
import metaApi from './metaAapi' //引入接口模块
import sourceAapi from './sourceAapi' 
import textAapi from './textAapi' 

//引入的模块都是一个个对象,进行解构,统一放到一个全局接口中
const apiMapper = {
    ...metaApi
    ...sourceAapi
    ...textAapi
}
exprot default apiMapper

解析出来可以看到apiMapper的具体样子

image.png

对上面的apiMapper的type处理

apiMapper的type主要是对接口的一个类型的备注,虽然都是get类型,但是可能传送参数的配置不同,所以先进行备注,接着通过serviceType文件来对备注进行归类,设置备注对应的请求方式。

//serviceType.js

const get = {
  "get-body":'GET',
  "get-quert":'GET',
  "get":'GET',
}
const post = {
  "post-body":'POST',
  "post-quert":'POST',
  "post":'GET',
}
const del = {
  'delete': 'DELETE',
  'delete-body': 'DELETE'
};
export default {
  ...get,
  ...post,
  ...del,
}

按接口类型进行配置

设置一个getconfig函数,进行config配置的设置,传入的是上方接口的类型备注,按照不同的类型设置各类类型的请求头,比如getgetbody虽然都是method都是get,但是config内容不同,get需要对参数进行序列化

这里我们引入qs插件对参数进行序列化,paramsSerializer不同的配置参数的序列化格式不同

data:{
  areaID:'11',
  area:'11',
  apiKey:'11',
  dayList:[1,2,3,4]
},
paramsSerializer: (data) => qs.stringify(data, { indices: false }),

image.png

import typeMap from "./serviceType";
export  function getConfig(type,body=undefined,query=undefined){
  let conf = {};
  switch(type){
    case 'get':
      conf = {
        params: query,
        paramsSerializer(params) {
            return qs.stringify(params, {
                arrayFormat: 'repeat'
            })
        },
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
        },
        responseType: 'json'
    }
    break;
    case 'get-body':
      conf = {
          params: query,
          headers: {
              'Content-Type': 'application/json'
          },
          responseType: 'json'
      };
    break;
    case 'postJSON':
            conf = {
                data: data,
                headers: {
                    'Content-Type': 'application/json',
                }
            }
            break;
    case 'download-param':
      conf = {
          params: data,
          paramsSerializer(params) {
              return qs.stringify(params, { arrayFormat: 'repeat' })
          },
          headers: {
              'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
          },
          responseType: 'blob'
      }
    break;
  }
  conf.method = typeMap[type]
  return conf
}

最后method从typeMap中取出,也就是上一节的内容,最后将整个完整的config返回

axios请求配置(拦截器,基本配置)

接着这边是实例,引入接口功能集成、类型、配置

设置接口的超时时间,configJWT是对请求头增加token标识

import reqUrlMap from './mapping';
import serviceType from './serviceType'
import {getConfig} from './serviceConfig'

axios.defaults.timeout = 500000;
axios.defaults.baseURL = '';
let $axios = axios.create();
const axiosXhr = axios.create();
function configJWT(config) {
  let token = `this is my token`;
  config.headers['Authorization'] = token;
  return config;
}

请求拦截器

使用interceptors.request进行请求拦截,对config重新设置,并且拦截器处发生错误会进行抛错

$axios.interceptors.request.use(
  config => {
      let configGhost = configJWT(config);
      return configGhost;
  },
  error => {
      msg({
          message: '请求异常,请联系管理员',
          type: 'error'
      });
      return Promise.reject(error);
  }
);

抛出axios请求实例

抛出一个异步函数接收,如果请求没有传入alias别名,则返回一个空对象,通过alias别名在mapping中获取接口类型最后把所有配置集成请求axios,这里的axios返回的是一个promise,所以这里用await便于我们请求doRequest请求可以用到then和catch


export default {
  async doRequest({
        alias = '',
        query,
        body,
        params
    } = {}) {
        let cfg;
        let url;
        let type;
        if (!alias) {
            return {};
        }
        type = reqUrlMap[alias].type;
        url = reqUrlMap[alias].url
        url = `api/${url}`;
        cfg = { 
            url,
            ...getConfig(type, query, body)
        };
        return await $axios(cfg);
    }
}

请求例子

最后我们发送一个请求,发送的请求配置如下

http.doRequest({
    alias:'aa-api',
    data:{
      areaID:'11',
      arr:[{name:11,age:22}]
    }
    }).then((res)=>{
    console.log(res)
})

token设置发送正常 image.png 但是我们看到返回的参数是嵌套了多层的,所以需要使用一个响应拦截器对responce进行处理

image.png

响应拦截

本来响应返回的是respone,现在我们返回的是responce.data,这样方便我们在请求处理返回内容的时候可以少写一层

$axios.interceptors.response.use(
    response => {
        return response.data
    },
    error => {
        msg({
            message: '请求异常,请联系管理员',
            type: 'error'
        });
        return Promise.reject(error);
    }
);

image.png