axios服务封装,可用于任何支持axios的项目中,包括react和vue都可通用。get/post请求,以及并发请求。以及导航栏随意切换测试/正式环境

版权声明:【原创】GitHub:https://github.com/susuGirl,微信公众号:fuxiaodexing,博客:https://blog.csdn.net/weixin_41845146 https://blog.csdn.net/weixin_41845146/article/details/84783380

任何项目,只要支持axios,那么你只要把我现在封装的服务整个文件夹考过去即可。这个原本是我封装在vue里的,但是有一天公司突然来一个紧急的H5微信分享活动的项目,我当时用react搭建(zepto+node搭建其实最好)也是为了挑战一下自己,毕竟只有三天时间。所以当我把很多vue里封装的东西直接拷到react项目时,居然发现一点毛病都没有,我瞬间觉得自己好机智,之前没有怕浪费时间随便封装。其中包括axios服务,拷到react项目毫无毛病的就跑起来,surprise!!!

文件夹结构:

  • 原理就是获取导航栏地址然后正则匹配字符串
// config.js

let env = ''
if ((/env=online/.test(window.location.href))) {
  env = 'online'
} else if ((/env=dev/.test(window.location.href))) {
  env = 'dev'
} else {
  env = 'dev' // 默认环境
}
const SERVER_URL = {
  online: { // 正式环境
    SERVER_URL1: '',
    SERVER_URL2: '',
    SERVER_URL3: ''
  },
  dev: { // 测试环境
    SERVER_URL1: '',
    SERVER_URL2: '',
    SERVER_URL3: ''
  }
}
export default SERVER_URL[env]

env的功能是为了方便地址栏直接切换环境,开发时我们用的是后台的测试接口,上线时用的是线上接口,栗子:

  • 测试环境:http://0.0.0.0:8082/#/entry/entryIndex
  • 切换到
  • 正式环境:http://0.0.0.0:8082/?env=online/#/entry/entryIndex
     
  • 封装axios实例
  • 配置响应拦截/请求拦截
    • 响应拦截这儿主要就是处理一下后端传的code值,因为后台小哥哥老是这个传字符串那个传数字,心塞塞~
  • 并发请求
    • axios.all 是axios的静态方法,不是实例上的方法,所以要在实例上做操作

// interApi.js

import axios from 'axios'
import config from './config'

// 配置 axios,并生成实例
const creatAxios1 = axios.create({
  baseURL: config.SERVER_URL1,
  withCredentials: true
})

// 拦截器配置
creatAxios1.interceptors.request.use(configData => { // 请求拦截 在发送请求之前做些什么
  // 请求成功做的事情 configData 中包含:url、method等信息
  return configData
}, error => { // 请求失败做的事情
  return Promise.reject(error)
})

creatAxios1.interceptors.response.use(response => { // 响应拦截 对响应数据做点什么
  // 响应成功做的事情
  response.data.code = Number(response.data.code) // 将接口返回的状态值 code 处理为数字
  return response
}, error => { // 响应失败做的事情
  return Promise.reject(error)
})

function sendAll (arr) { // 顺序和请求发送的顺序相同,使用 axios.spread 分割成多个单独的响应对象
  if (Object.prototype.toString.call(arr) === '[object Array]') {
    return axios.all(arr).then(axios.spread(function (...res) { // axios.all 是axios的静态方法,不是实例上的方法
      // 请求全部都执行完成
      return Promise.resolve(res)
    }))
  } else {
    const error = new Error('参数错误!')
    try {
      throw error
    } catch (e) {
      // console.log(e)
    }
  }
}

export default {
  creatAxios1,
  sendAll
}
  • 暴露 API 方法:get请求 post请求  并发请求
// extendsApi.js

/* eslint-disable no-useless-constructor */
import api from './interApi'
import qs from 'qs'
import config from './config'

function _apiFn (baseUrl) { // 该方法对外不可见
  if (baseUrl === 'service2') {
    api.creatAxios1.defaults.baseURL = config.SERVER_URL2 // 改变 axios 实例的 baseURL
  } else if (baseUrl === 'service3') {
    api.creatAxios1.defaults.baseURL = config.SERVER_URL3
  } else {
    api.creatAxios1.defaults.baseURL = config.SERVER_URL1
  }
}
class axiosApi {
  constructor () {

  }

  sendGet (url, params = {}, baseUrl) { // get 请求
    if (Object.prototype.toString.call(params) === '[object Object]') {
      _apiFn(baseUrl)
      return api.creatAxios1.get(url, {params: params})
    } else {
      const error = new Error('参数错误!')
      try {
        throw error
      } catch (e) {
        // console.log(e)
      }
    }
  }

  sendPost (url, params = {}, baseUrl) { // post 请求
    if (Object.prototype.toString.call(params) === '[object Object]') {
      _apiFn(baseUrl)
      return api.creatAxios1.post(url, qs.stringify(params))
    } else {
      const error = new Error('参数错误!')
      try {
        throw error
      } catch (e) {
        // console.log(e)
      }
    }
  }

  /**
   * 并发请求,同时发送多个请求,使用栗子:src/views/infoEntry/dragCard/dragCardService.js
   * 顺序和请求发送的顺序相同
   * @param {arr: [请求1,请求2...]}
   */

  sendAll (arr) { // 并发请求
    return new Promise((resolve, reject) => {
      api.sendAll(arr).then(res => {
        return resolve(res)
      })
    })
  }
}

export default axiosApi
  • 公共服务使用方法
// index.js

// commit API
import extendsApi from './extendsApi'

class AllServiceApi extends extendsApi {
  constructor () {
    super()
    this.demoUrl = ''
  }
  demoGet (params) {
    return this.sendGet(this.demoUrl, params).then(res => {
      return res.data
    })
  }
}

export default new AllServiceApi()
  • 组件中的使用方法

// commit API
import extendsApi from 'services/extendsApi'

class LoginServiceApi extends extendsApi {
  constructor () {
    super()
    this.demoUrl = ''
  }
  demoGet (params) {
    return this.sendGet(this.demoUrl, params).then(res => {
      return res.data
    })
  }
}

export default new LoginServiceApi()

全局公共服务/组件的私有服务,如上封装以及使用即可。

猜你喜欢

转载自blog.csdn.net/weixin_41845146/article/details/84783380
今日推荐