首先观察一下项目目录,本次的主题是封装一套axios,封装的内容就放在图中的api目录下。
一个完整的axios
,首先我们会想到什么呢?应该是路由,对吧,我们先建一个路由config.js
,来控制不同环境的路由设置。
/**
* 配置不同环境接口前缀
* 如果未配置dev为默认配置
* @param {*} base
* @example
* {
* dev: 'dev环境配置信息',
* test: 'test环境配置信息',
* prod: '线上环境配置信息'
* }
*/
function conf (base = {}) {
if (process.env.NODE_ENV === 'production') { // 生产环境下
let env = process.env.ENV_CONFIG || 'dev'
return base[env] || base['dev']
}
// 开发环境
return base['dev']
}
// PORTAL 接口
export const POR_LOGIN_LOGOUT = conf({
dev: 'http://`````',
test: 'http://`````',
prod: 'http://`````'
})
这种设置很适合一个项目中分很多模块,且不同模块之间的接口不同,如果是项目中大多数接口地址前缀都相同的话,那其实还可以简化一下路由这块,视需求来定。
路由解决了,接下来当然就是建立axios
请求啦,让我们建立一个request.js
文件。
import axios from 'axios'
import store from '@/store'
import {POR_LOGIN_LOGOUT} from './config'
/* eslint-disable */
// portal base
export const porApi = axios.create({
baseURL: POR_LOGIN_LOGOUT, // api 的 base_url
timeout: 15000, // request timeout
headers: {
'Content-Type': 'application/json'
}
})
porApi.defaults.headers.get['Content-Type']= 'application/x-www-form-urlencoded'
这样我们每个axios
请求的基础api
是不是就完成,我们肯定是不想每次都写post
和get
的对吧,这样就到了终极的axios
封装问题啦,让我们建一个request-api.js
来解决这个问题。
/**
* 公用方法集合
*/
const requestData = (nAxios, methods, url, datas, headers, timeout) => {
let options = Object.assign({}, {
url: url,
method: methods,
data: datas
})
if (headers) {
options.headers = headers
}
if (timeout) {
options.timeout = timeout
}
let listPromise = new Promise((resolve, reject) => {
nAxios.request(options)
.then(res => {
resolve(res)
}).catch(res => {
reject(res)
})
})
return listPromise
}
const queryData = (nAxios, url, query) => {
let tempQuery = ''
if (url.indexOf('?') === -1) {
tempQuery = '?'
}
for (let key in query) {
if (query[key] !== null && query[key] !== undefined && query[key] !== '' && query[key].length !== 0) {
tempQuery += '&' + key + '=' + query[key]
}
}
let listPromise = new Promise((resolve, reject) => {
nAxios.get(encodeURI(url + tempQuery)).then((rst) => {
resolve(rst)
}).catch(error => {
reject(error)
})
})
return listPromise
}
post
和get
我们都封装好了,是不是直接调用就可以啦,我比较推荐的是将接口具体调用分模块放在一起,而不是在vue
业务代码里写很多接口调用,所以在我这还有一层就是接口的具体调用api
,因为我之前建的api
是porApi
,所以我们就以它来命名接口调用的js文件吧。
import {porApi} from './request'
import {requestData, queryData} from './request-api'
// 获取权限和用户名
export const getNameDetail = (count) => {
return requestData(porApi, 'get', `/api/employee/info/query`)
}
在具体的业务代码里,我们只要引入类似getNameDetail
这样的方法就好了,返回的是promise
,完全可以满足大部分场景需要。经常需要的拦截,我们也可以在request.js
里封装好,就看具体需要了。
porApi.interceptors.response.use(responseInterceptor, errorResponseInterceptor)
porApi.interceptors.request.use(requestInterceptor, errorRequestInterceptor)
这样的封装在我看来是比较完整的,有些地方也可以视项目情况进行删减,总之,快乐开发最重要。