
首先觀察一下項(xiàng)目目錄,本次的主題是封裝一套axios,封裝的內(nèi)容就放在圖中的api目錄下。
一個(gè)完整的axios,首先我們會(huì)想到什么呢?應(yīng)該是路由,對(duì)吧,我們先建一個(gè)路由config.js,來(lái)控制不同環(huán)境的路由設(shè)置。
/**
* 配置不同環(huán)境接口前綴
* 如果未配置dev為默認(rèn)配置
* @param {*} base
* @example
* {
* dev: 'dev環(huán)境配置信息',
* test: 'test環(huán)境配置信息',
* prod: '線上環(huán)境配置信息'
* }
*/
function conf (base = {}) {
if (process.env.NODE_ENV === 'production') { // 生產(chǎn)環(huán)境下
let env = process.env.ENV_CONFIG || 'dev'
return base[env] || base['dev']
}
// 開(kāi)發(fā)環(huán)境
return base['dev']
}
// PORTAL 接口
export const POR_LOGIN_LOGOUT = conf({
dev: 'http://`````',
test: 'http://`````',
prod: 'http://`````'
})
這種設(shè)置很適合一個(gè)項(xiàng)目中分很多模塊,且不同模塊之間的接口不同,如果是項(xiàng)目中大多數(shù)接口地址前綴都相同的話,那其實(shí)還可以簡(jiǎn)化一下路由這塊,視需求來(lái)定。
路由解決了,接下來(lái)當(dāng)然就是建立axios請(qǐng)求啦,讓我們建立一個(gè)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'
這樣我們每個(gè)axios請(qǐng)求的基礎(chǔ)api是不是就完成,我們肯定是不想每次都寫(xiě)post和get的對(duì)吧,這樣就到了終極的axios封裝問(wèn)題啦,讓我們建一個(gè)request-api.js來(lái)解決這個(gè)問(wèn)題。
/**
* 公用方法集合
*/
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我們都封裝好了,是不是直接調(diào)用就可以啦,我比較推薦的是將接口具體調(diào)用分模塊放在一起,而不是在vue業(yè)務(wù)代碼里寫(xiě)很多接口調(diào)用,所以在我這還有一層就是接口的具體調(diào)用api,因?yàn)槲抑敖ǖ?code>api是porApi,所以我們就以它來(lái)命名接口調(diào)用的js文件吧。
import {porApi} from './request'
import {requestData, queryData} from './request-api'
// 獲取權(quán)限和用戶名
export const getNameDetail = (count) => {
return requestData(porApi, 'get', `/api/employee/info/query`)
}
在具體的業(yè)務(wù)代碼里,我們只要引入類(lèi)似getNameDetail這樣的方法就好了,返回的是promise,完全可以滿足大部分場(chǎng)景需要。經(jīng)常需要的攔截,我們也可以在request.js
里封裝好,就看具體需要了。
porApi.interceptors.response.use(responseInterceptor, errorResponseInterceptor)
porApi.interceptors.request.use(requestInterceptor, errorRequestInterceptor)
這樣的封裝在我看來(lái)是比較完整的,有些地方也可以視項(xiàng)目情況進(jìn)行刪減,總之,快樂(lè)開(kāi)發(fā)最重要。