vue中的axios配置及接口請(qǐng)求路徑api配置
簡(jiǎn)介
關(guān)于vue中使用axios請(qǐng)求的配置,注意其中區(qū)分Vue2.0和Vue3.0的寫(xiě)法。
一、axios配置
由于可能會(huì)有多個(gè)插件應(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; } // 對(duì)Blob對(duì)象進(jìn)行處理 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); // 注冊(cè)all方法,執(zhí)行多個(gè)并發(fā)請(qǐng)求 // 可傳入Promise、包含Promise的數(shù)組、返回值為Promise的方法 _axios.all = (...requsets) => { // 獲取所有Promise對(duì)象 let promiseList = getAllPromise(requsets); return new Promise((resolve, reject) => { axios .all(promiseList) .then( axios.spread((...response) => { // 兩個(gè)請(qǐng)求現(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) // 用來(lái)判斷是否請(qǐng)求成功 const success = response.status === 200; let messages = ''; if (!success) { if (typeof response.data === 'string') { messages = '服務(wù)器錯(cuò)誤,未獲取到響應(yīng)數(shù)據(jù)'; } else { if (response.status === 200) { return Promise.reject(response); } // 請(qǐng)求成功,但在業(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("您的登錄已過(guò)期,請(qǐng)重新登錄"); // 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(`客戶(hù)端錯(cuò)誤,狀態(tài)碼:${status}`); } else if (status >= 500) { console.error(`服務(wù)器錯(cuò)誤,狀態(tài)碼:${status}`); } // 系統(tǒng)請(qǐ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對(duì)象,組成數(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ù)的類(lèi)型是否符合預(yù)期 * 只傳一個(gè)參數(shù)data,則返回?cái)?shù)據(jù)的類(lèi)型; * 傳入多個(gè)參數(shù),則判斷數(shù)據(jù)是否屬于該類(lèi)型(或?qū)儆陬?lèi)型數(shù)組中的一個(gè)) * @param {*} data 需要判斷類(lèi)型的數(shù)據(jù) * @param {...any} typeList 字符串或字符串?dāng)?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)核上會(huì)報(bào)錯(cuò),重寫(xiě) * @param {Array} list 目標(biāo)數(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ā)一個(gè)DOM事件 * @param {Element} node 事件發(fā)生的節(jié)點(diǎn)元素 * @param {String} name 事件名稱(chēng),不含前綴:on * @param {...any} options 可選的事件配置項(xiàng) */ 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); }
二、請(qǐng)求接口路徑api配置
自行根據(jù)目錄結(jié)構(gòu)新建文件。
方便區(qū)分接口所屬模塊,于是根據(jù)接口分類(lèi)進(jìn)行新建js文件。
1. api集合中心(‘api/index.js’)
'use strict'; /* eslint-disable no-unused-vars */ /** 有幾個(gè)模塊,subList就有幾個(gè)元素 * @param: name 子系統(tǒng)名稱(chēng) * @param: url 子系統(tǒng)使用的環(huán)境變量(請(qǐng)求地址,便于不同模塊請(qǐng)求不同服務(wù)器的配置,可在三個(gè)環(huán)境中新增類(lèi)似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. 模塊分類(lèi)一:user(‘api/user.js’)
/* 用戶(hù)相關(guān)api */ export default { API_LIST_USER: { // 登錄 INTERFACE_GET_USER_LOGIN: 'user/login', // 查詢(xún)管理員列表 INTERFACE_GET_USER_LIST: 'admin/users', // 新增管理員 INTERFACE_POST_USER_ADMIN: 'admin/register', // 刪除管理員 INTERFACE_DELETE_USER_ADMIN: 'admin/users', }, };
3. 模塊分類(lèi)二:管理(‘api/management.js’)
/* 管理相關(guān)api * @param: key => 子系統(tǒng)名稱(chē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'; // 注冊(cè)自定義插件 import moduleFiles from './plugins'; // 引入api地址 import apiList from '@/api'; // 批量使用自定義插件 moduleFiles.keys().forEach(modulePath => { Vue.use(moduleFiles(modulePath).default); }); // 注冊(cè)所有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'); // 注冊(cè)所有api地址為全局變量 app.config.globalProperties.$_API = apiList; // 批量使用自定義插件 moduleFiles.keys().forEach((modulePath) => { app.use(moduleFiles(modulePath).default); });
四、請(qǐng)求接口的使用方式
以下是vue2.x的使用方式
// 其中 url為接口地址,在api目錄下定義 // config內(nèi)容為參數(shù)和其他配置,例如: --------------------------執(zhí)行 GET 請(qǐng)求--------------------------------- // 執(zhí)行 GET 請(qǐng)求 this.$_http.get('url' + "?ID=12345") .then(response => { // 自己的操作 console.log(response); }) // 不需要寫(xiě)catch,axios配置會(huì)自動(dòng)提示出來(lái) // 可選地,上面的請(qǐng)求可以這樣寫(xiě) this.$_http.get('url', { params: { ID: 12345 } }).then(response => { // 自己的操作 console.log(response); }) --------------------------執(zhí)行 POST 請(qǐng)求--------------------------------- // 執(zhí)行 POST 請(qǐng)求 this.$_http.post('url', { firstName: "Fred", lastName: "Flintstone" }).then(response => { // 自己的操作 console.log(response); }) --------------------------執(zhí)行 DELETE 請(qǐng)求--------------------------------- // 執(zhí)行 POST 請(qǐng)求 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請(qǐng)求結(jié)果", res); }) }
注意
在 axios.js 中,關(guān)于 console.error 相關(guān)的部分,替換為自己項(xiàng)目所引入的ui框架的消息提示即可,如 ant Design 的 message,就有請(qǐng)求后報(bào)錯(cuò)的相關(guān)提示。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Vue.js組件tree實(shí)現(xiàn)無(wú)限級(jí)樹(shù)形菜單
這篇文章主要為大家詳細(xì)介紹了Vue.js組件tree實(shí)現(xiàn)無(wú)限級(jí)樹(shù)形菜單代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12Vant中Popover氣泡彈出框位置錯(cuò)亂問(wèn)題解決
這篇文章主要為大家介紹了Vant中Popover氣泡彈出框位置錯(cuò)亂問(wèn)題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06vue keep-alive的簡(jiǎn)單總結(jié)
這篇文章主要介紹了vue中的keep-alive的相關(guān)資料,幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下2021-01-01Vue3全局掛載使用Axios學(xué)習(xí)實(shí)戰(zhàn)
這篇文章主要為大家介紹了Vue3全局掛載使用Axios學(xué)習(xí)實(shí)戰(zhàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06vue打包后出現(xiàn)空白頁(yè)的原因及解決方式詳解
在項(xiàng)目中很多時(shí)候需要用到vue打包成html不需要放在服務(wù)器上就能瀏覽,根據(jù)官網(wǎng)打包出來(lái)的html直接打開(kāi)是顯示空白,下面這篇文章主要給大家介紹了關(guān)于vue打包后出現(xiàn)空白頁(yè)的原因及解決方式的相關(guān)資料,需要的朋友可以參考下2022-07-07