1. 程式人生 > >axios服務封裝,可用於任何支援axios的專案中,包括react和vue都可通用。get/post請求,以及併發請求。以及導航欄隨意切換測試/正式環境

axios服務封裝,可用於任何支援axios的專案中,包括react和vue都可通用。get/post請求,以及併發請求。以及導航欄隨意切換測試/正式環境

任何專案,只要支援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()

全域性公共服務/元件的私有服務,如上封裝以及使用即可。