版权声明:【原创】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()
全局公共服务/组件的私有服务,如上封装以及使用即可。