vue中的axios配置及接口請求路徑api配置
簡介
關(guān)于vue中使用axios請求的配置,注意其中區(qū)分Vue2.0和Vue3.0的寫法。
一、axios配置
由于可能會有多個插件應(yīng)用,所以有了plugins(utils里面放的是封裝的事件處理方法),自行新建相關(guān)文件

1.安裝axios
npm install axios --save
2.‘plugins/index.js’ 配置
// 導(dǎo)出所有插件
let moduleFiles = require.context('./modules', true, /\.js$/);
export default moduleFiles;
3.'axios.js’配置
'use strict';
import axios from 'axios';
// import store from "@/store";
// import { message } from "ant-design-vue"
import { getAllPromise } from '@/utils/tools';
import { triggerEvent } from '@/utils/events';
// 完整配置參考: https://github.com/axios/axios#request-config
axios.defaults.headers.post['Content-Type'] = 'application/json;charset=utf-8';
axios.defaults.headers.put['Content-Type'] = 'application/json;charset=utf-8';
axios.defaults.headers.delete['Content-Type'] =
'application/json;charset=utf-8';
let config = {
baseURL: process.env.VUE_APP_BASE_API || process.env.apiUrl || '',
timeout: 60 * 1000,
withCredentials: false,
crossDomain: true,
transformRequest: [
(data) => {
if (!data || typeof data === 'string') {
return data;
}
if (data instanceof FormData) {
return data;
}
// 對Blob對象進行處理
let hasBlob = Object.values(data).some((it) => {
return it instanceof Blob;
});
if (!hasBlob) {
return JSON.stringify(data);
}
const formData = new FormData();
Object.entries(data).forEach(([key, value]) => {
formData.append(key, value);
});
return formData;
},
],
};
const _axios = axios.create(config);
// 注冊all方法,執(zhí)行多個并發(fā)請求
// 可傳入Promise、包含Promise的數(shù)組、返回值為Promise的方法
_axios.all = (...requsets) => {
// 獲取所有Promise對象
let promiseList = getAllPromise(requsets);
return new Promise((resolve, reject) => {
axios
.all(promiseList)
.then(
axios.spread((...response) => {
// 兩個請求現(xiàn)在都執(zhí)行完成
resolve(response);
})
)
.catch((error) => {
reject(error);
});
});
};
_axios.interceptors.request.use(
(config) => {
// const token = getCookie(AUTH_TOKEN_FRONT);
// config.headers.common[AUTH_TOKEN_END] = token;
const token = 'AUTH_TOKEN_FRONT';
config.headers.common.Token = token;
return config;
},
(error) => {
return Promise.reject(error);
}
);
// 攔截響應(yīng)
_axios.interceptors.response.use(
(response) => {
// console.log(response)
// 用來判斷是否請求成功
const success = response.status === 200;
let messages = '';
if (!success) {
if (typeof response.data === 'string') {
messages = '服務(wù)器錯誤,未獲取到響應(yīng)數(shù)據(jù)';
} else {
if (response.status === 200) {
return Promise.reject(response);
}
// 請求成功,但在業(yè)務(wù)上為失敗
messages = response.message || response.statusText || '操作執(zhí)行失敗';
}
console.error(messages);
return Promise.reject(response);
}
return {
data: response.data,
success,
messages,
};
},
(error) => {
if (!navigator.onLine) {
triggerEvent(window, 'offline');
return Promise.reject(error);
}
if (!error.response) {
console.error('連接服務(wù)器失敗');
return Promise.reject(error);
}
let status = error.response.status;
if (status === 401) {
// message.error("您的登錄已過期,請重新登錄");
// window.location.reload();
// store.dispatch("user/logout");
return Promise.reject(error);
}
if (status < 200) {
console.warning(`未處理的消息響應(yīng),狀態(tài)碼:${status}`);
} else if (status >= 300 && status < 400) {
console.warning(`未處理的重定向響應(yīng),狀態(tài)碼:${status}`);
} else if (status >= 400 && status < 500) {
console.error(`客戶端錯誤,狀態(tài)碼:${status}`);
} else if (status >= 500) {
console.error(`服務(wù)器錯誤,狀態(tài)碼:${status}`);
}
// 系統(tǒng)請求失敗
return Promise.reject(error);
}
);
// -------------------------vue2.x導(dǎo)出-------------------------
// export default {
// install: (Vue) => {
// Vue.$_http = _axios;
// window.$_http = _axios;
// Object.defineProperties(Vue.prototype, {
// $_http: {
// get() {
// return _axios;
// },
// },
// });
// },
// };
// -------------------------vue3.x導(dǎo)出-------------------------
export default {
install: (app) => {
app.$_http = _axios;
window.$_http = _axios;
Object.defineProperties(app.config.globalProperties, {
$_http: {
get() {
return _axios;
},
},
});
},
};
4.'utils/tools.js’配置
/**
* 從參數(shù)中獲取所有Promise對象,組成數(shù)組并返回
* @param {...any} datas 待解析數(shù)據(jù)
*/
export function getAllPromise(...datas) {
let promiseList = [];
datas.forEach((it) => {
if (isDataType(it, 'Promise')) {
promiseList.push(it);
return;
}
// 是方法則獲取執(zhí)行的結(jié)果
if (isDataType(it, 'Function')) {
promiseList.push(...getAllPromise(it()));
return;
}
if (isDataType(it, 'Array')) {
promiseList.push(...getAllPromise(...it));
}
});
return promiseList;
}
/**
* 判斷數(shù)據(jù)的類型是否符合預(yù)期
* 只傳一個參數(shù)data,則返回數(shù)據(jù)的類型;
* 傳入多個參數(shù),則判斷數(shù)據(jù)是否屬于該類型(或?qū)儆陬愋蛿?shù)組中的一個)
* @param {*} data 需要判斷類型的數(shù)據(jù)
* @param {...any} typeList 字符串或字符串數(shù)組,可不傳
*/
export function isDataType(data, ...typeList) {
let dataType = Object.prototype.toString
.call(data)
.replace(/^\[object/, '')
.replace(/\]$/, '')
.replace(/\s/, '');
typeList = flat(typeList);
let hasType = typeList.some((it) => {
return it && isDataType(it) === 'String';
});
if (!hasType) {
return dataType;
}
if (
typeList.includes(dataType) ||
typeList.includes(dataType.toLowerCase())
) {
return true;
}
return false;
}
/**
* Array.flat在app和Trident內(nèi)核上會報錯,重寫
* @param {Array} list 目標數(shù)組
*/
export function flat(list) {
if (Array.prototype.flat) {
return list.flat(Infinity);
}
let retArr = [];
if (!Array.isArray(list)) {
throw new Error(
`Invalid parameter: type check failed for parameter 'list'. Expected Array, But got ${typeof list} with value ${list}`
);
}
list.forEach((it) => {
if (!Array.isArray(it)) {
retArr.push(it);
return;
}
retArr.push(...flat(it));
});
return retArr;
}
5.'utils/events.js’配置
// 瀏覽器中的事件管理
/**
* 觸發(fā)一個DOM事件
* @param {Element} node 事件發(fā)生的節(jié)點元素
* @param {String} name 事件名稱,不含前綴:on
* @param {...any} options 可選的事件配置項
*/
export function triggerEvent(node, name, ...options) {
if (node.fireEvent) {
return node.fireEvent('on' + name);
}
let eventName;
let evt;
if (/^mouse|click/.test(name)) {
eventName = 'MouseEvents';
evt = document.createEvent(eventName);
evt.initMouseEvent(name, ...options);
} else if (['DOMActivate', 'DOMFocusIn', 'DOMFocusOut'].includes(name)) {
eventName = 'UIEvents';
evt = document.createEvent(eventName);
evt.initUIEvent(name, ...options);
} else if (/^key/.test(name)) {
eventName = 'KeyboardEvent';
evt = document.createEvent(eventName);
evt.initKeyboardEvent(name, ...options);
} else if (name.startsWith('DOM')) {
eventName = 'MutationEvents';
evt = document.createEvent(eventName);
evt.initMutationEvent(name, ...options);
} else {
eventName = 'HTMLEvents';
evt = document.createEvent(eventName);
evt.initEvent(name, ...options);
}
return node.dispatchEvent(evt);
}
二、請求接口路徑api配置
自行根據(jù)目錄結(jié)構(gòu)新建文件。
方便區(qū)分接口所屬模塊,于是根據(jù)接口分類進行新建js文件。

1. api集合中心(‘api/index.js’)
'use strict';
/* eslint-disable no-unused-vars */
/** 有幾個模塊,subList就有幾個元素
* @param: name 子系統(tǒng)名稱
* @param: url 子系統(tǒng)使用的環(huán)境變量(請求地址,便于不同模塊請求不同服務(wù)器的配置,可在三個環(huán)境中新增類似VUE_APP_BASE_API的域名地址變量)
*/
const subList = [
{
name: 'API_LIST_USER',
url: 'VUE_APP_BASE_API',
},
{
name: 'API_LIST_MANAGEMENT',
url: 'VUE_APP_BASE_API',
},
];
// 所有api子系統(tǒng)
let API_LIST = {};
const moduleFiles = require.context('./modules', true, /\.js$/);
moduleFiles.keys().forEach((modulePath) => {
API_LIST = { ...API_LIST, ...moduleFiles(modulePath).default };
});
// 合成API地址集合
let apiList = {};
subList.forEach((it) => {
let subApi = Object.entries(API_LIST[it.name]).reduce(
(target, [key, value]) => {
target[key] = process.env[it.url].replace(/\W*$/, '') + '/' + value.replace(/^\W*/, '');
return target;
},
{}
);
apiList = { ...apiList, ...subApi };
});
export default apiList;
2. 模塊分類一:user(‘api/user.js’)
/* 用戶相關(guān)api */
export default {
API_LIST_USER: {
// 登錄
INTERFACE_GET_USER_LOGIN: 'user/login',
// 查詢管理員列表
INTERFACE_GET_USER_LIST: 'admin/users',
// 新增管理員
INTERFACE_POST_USER_ADMIN: 'admin/register',
// 刪除管理員
INTERFACE_DELETE_USER_ADMIN: 'admin/users',
},
};
3. 模塊分類二:管理(‘api/management.js’)
/* 管理相關(guān)api
* @param: key => 子系統(tǒng)名稱,用于api/index.js中
*/
export default {
API_LIST_MANAGEMENT: {
// 工種列表
INTERFACE_GET_ENGINEERINGWORK_LIST: '/engineertypes',
// 新建工種
INTERFACE_POST_ENGINEERINGWORK_CREATE: '/admin/engineertype',
// 刪除工種
INTERFACE_DELETE_ENGINEERINGWORK_DELETE: '/admin/engineertype/{engineertypeid}',
},
};
三、axios和接口api的全局注入
(1)vue2.x
import Vue from 'vue';
import App from './App.vue';
// 注冊自定義插件
import moduleFiles from './plugins';
// 引入api地址
import apiList from '@/api';
// 批量使用自定義插件
moduleFiles.keys().forEach(modulePath => {
Vue.use(moduleFiles(modulePath).default);
});
// 注冊所有api地址為全局變量
Vue.prototype.$_API = apiList;
new Vue({
render: (h) => h(App),
}).$mount('#app');
(2)vue3.x
import { createApp } from 'vue';
import App from './App.vue';
// 引入自定義插件
import moduleFiles from './plugins';
// 引入api地址
import apiList from '@/api';
const app = createApp(App);
app.mount('#app');
// 注冊所有api地址為全局變量
app.config.globalProperties.$_API = apiList;
// 批量使用自定義插件
moduleFiles.keys().forEach((modulePath) => {
app.use(moduleFiles(modulePath).default);
});
四、請求接口的使用方式
以下是vue2.x的使用方式
// 其中 url為接口地址,在api目錄下定義
// config內(nèi)容為參數(shù)和其他配置,例如:
--------------------------執(zhí)行 GET 請求---------------------------------
// 執(zhí)行 GET 請求
this.$_http.get('url' + "?ID=12345")
.then(response => {
// 自己的操作
console.log(response);
})
// 不需要寫catch,axios配置會自動提示出來
// 可選地,上面的請求可以這樣寫
this.$_http.get('url', {
params: {
ID: 12345
}
}).then(response => {
// 自己的操作
console.log(response);
})
--------------------------執(zhí)行 POST 請求---------------------------------
// 執(zhí)行 POST 請求
this.$_http.post('url', {
firstName: "Fred",
lastName: "Flintstone"
}).then(response => {
// 自己的操作
console.log(response);
})
--------------------------執(zhí)行 DELETE 請求---------------------------------
// 執(zhí)行 POST 請求
this.$_http.delete('url', {
data: { id: 1 }
}).then(response => {
// 自己的操作
console.log(response);
})
--------------------------案例---------------------------------------------
let params = {
page: 0,
size: 10,
};
this.$_http.get(this.$_API.INTERFACE_GET_USER_LIST, { params }).then((res) => {
console.log(res);
});
以下是vue3.x的使用方式
import { getCurrentInstance } from "vue"
setUp() {
// 方式一
// const internalInstance = getCurrentInstance()
// const globalProperties = internalInstance.appContext.config.globalProperties
// const _http = globalProperties.$_http
// const _API = globalProperties.$_API
// 方式二
const { proxy } = getCurrentInstance()
const _http = proxy.$_http
const _API = proxy.$_API
console.log(_http, _API)
let params = {
page: 0,
size: 10,
}
_http.get(_API.INTERFACE_GET_USER_LIST, { params }).then((res) => {
console.log("axios請求結(jié)果", res);
})
}
注意
在 axios.js 中,關(guān)于 console.error 相關(guān)的部分,替換為自己項目所引入的ui框架的消息提示即可,如 ant Design 的 message,就有請求后報錯的相關(guān)提示。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Vue3全局掛載使用Axios學(xué)習(xí)實戰(zhàn)
這篇文章主要為大家介紹了Vue3全局掛載使用Axios學(xué)習(xí)實戰(zhàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-06-06

