axios服務封裝,可用於任何支援axios的專案中,包括react和vue都可通用。get/post請求,以及併發請求。以及導航欄隨意切換測試/正式環境
阿新 • • 發佈:2018-12-14
任何專案,只要支援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()
全域性公共服務/元件的私有服務,如上封裝以及使用即可。