在Vue中是如何封裝axios
更新時間:2021年10月09日 09:51:59 作者:青蓮使者
這篇文章主要介紹在Vue中是如何封裝axios的相關(guān)資料,axios的封裝主要是幫助我們簡化代碼和利于后期的更新維護,感興趣的小伙伴可以和小編一起來閱讀下面文章的具體內(nèi)容
1、安裝
npm install axios; // 安裝axios
1、引入
import axios from 'axios'
3、接口根地址
const baseUrl = API_BASE_URL // 由webpack的插件DefinePlugin注入 webpackConfig .plugin('define') .use(require('webpack/lib/DefinePlugin'), [{ // NODE_ENV 環(huán)境變量,開發(fā)環(huán)境為: 'development', 為了保證測試環(huán)境打的包與生產(chǎn)環(huán)境一致,測試環(huán)境和生產(chǎn)環(huán)境都為'production' 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV), // 當前應用的環(huán)境(開發(fā)環(huán)境為: 'dev',測試環(huán)境為: 'test', 生產(chǎn)環(huán)境為: 'prod') 'process.env.APP_ENV': JSON.stringify(process.env.APP_ENV), // 后臺接口請求地址 'API_BASE_URL': JSON.stringify(config.meshProp('apiBaseUrl')), // 首頁路徑 'APP_INDEX_PATH': JSON.stringify(indexPath), // 路由模式 'APP_ROUTER_MODE': JSON.stringify(config.meshProp('routerMode')), // 是否使用Element組件庫 'APP_USE_ELEMENT': JSON.stringify(config.meshProp('useElement')), }])
config.js
:配置一些系統(tǒng)名稱,api根路徑等
const path = require('path') const os = require('os') const packageName = 'focm' // 項目包名稱 const localIP = getLocalIP() // 本地IP地址 module.exports = { // 默認配置 default: { // 系統(tǒng)名稱,用于設置頁面 head 中 title appName: 'xxxxx', // 是否為多頁應用 isMulti: false, // 是否支持移動端 isMobile: false, // 是否使用Element組件庫(https://element.eleme.cn/#/zh-CN/) useElement: true, // 路由模式(值為hash 或 history, 參考:https://router.vuejs.org/) routerMode: 'hash', // 接口請求根路徑 apiBaseUrl: '', .... }, // 開發(fā)環(huán)境的配置 dev: { apiBaseUrl: '/api', host: localIP, port: 8080, autoOpenBrowser: true, // 是否自動打開瀏覽器 writeToDisk: false, // 是否將生成的文件寫入磁盤 proxyTable: { '/api': { target: 'http://focm-web.focms.paas.test', changeOrigin: true } } }, // 測試環(huán)境的配置 test: { // 接口請求根路徑 apiBaseUrl: '/focm', outputRoot: path.resolve(__dirname, 'dist/test'), publish: { remoteHost: 'x.x.x.x', remotePort: '22', remoteUsername: 'qinglianshizhe', remotePassword: 'xxxxxx', remoteAppRoot: `/xxx/xxx/${packageName}`, webUrl: 'http://xxxxx.com/' } }, // 生產(chǎn)環(huán)境的配置 prod: { ... } } // 獲取本地IP function getLocalIP () { let interfaces = os.networkInterfaces() for(let devName in interfaces){ let iface = interfaces[devName] for(let i=0;i<iface.length;i++){ let alias = iface[i]; if(alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal){ return alias.address; } } } return 'localhost' }
我們繼續(xù)來封裝axios
/** * 業(yè)務異常類 */ class BusinessError extends Error { constructor (code, message, data) { super(message) this.code = code this.name = 'BusinessError' this.data = data } } /** * 系統(tǒng)異常類 */ class SystemError extends Error { constructor (code, message, data) { super(message) this.code = code this.name = 'SystemError' this.data = data } } // axios 配置 axios.defaults.timeout = 10000 axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8' // 執(zhí)行 POST 請求 function post (option, vm) { option.method = 'POST' return http(option, vm) } // 執(zhí)行 GET 請求 function get (option, vm) { option.method = 'GET' return http(option, vm) } // 下載請求 function download (option, vm) { option.method = option.method || 'GET' option.isDownload = true option.responseType = 'blob' return http(option, vm) } /** * 請求后臺接口 * @param option 參數(shù) * url: 請求路徑(會拼接到baseUrl后面,“/” 開頭) * data: 請求參數(shù)對象 * timeout: 請求超時時間(默認為:10000,即10秒) * toastError: 自動提示業(yè)務異常信息,默認為true,為false時不自動提示 * @param vm Vue對象(用于異常時自動toast提示異常信息) * @return {Promise} Promise對象 */ function http (option, vm) { return new Promise((resolve, reject) => { let method = option.method || 'POST' let url = baseUrl + option.url let timeout = option.timeout || 10000 let headers = option.headers || {} let responseType = option.responseType let data = {} // 可以在此設置默認值 if (option.data) { if (option.data instanceof FormData) { headers['Content-Type'] = 'multipart/form-data' let formData = option.data Object.keys(data).forEach((key) => { formData.append(key, data[key]) }) data = formData } else { data = { ...data, ...option.data } } } let requestOptions = { method, url, headers, timeout, responseType } if (method.toUpperCase() === 'GET') { requestOptions.params = data } else { requestOptions.data = data } axios(requestOptions).then( (res) => { const contentDisposition = res.headers['content-disposition'] // 文件下載 if (contentDisposition && (/filename\*=UTF-8''(.*)/.test(contentDisposition) || /filename="(.*)"/.test(contentDisposition))) { // 如果是文件下載 const utf8Match = contentDisposition.match(/filename\*=UTF-8''(.*)/) // 匹配UTF-8的文件名 const normalMatch = contentDisposition.match(/filename="(.*)"/) // 匹配普通英文文件名 const filename = utf8Match ? decodeURIComponent(utf8Match[1]) : normalMatch[1] const blob = new Blob([res.data]) const downloadElement = document.createElement('a') const href = window.URL.createObjectURL(blob) downloadElement.href = href downloadElement.download = filename document.body.appendChild(downloadElement) downloadElement.click() document.body.removeChild(downloadElement) window.URL.revokeObjectURL(href) resolve(res) } else { // JSON信息 getResponseInfo(res).then((resInfo) => { responseInfoHandle(resInfo, resolve, reject, option, vm, requestOptions) }) } }, err => { errorhandle(err, reject, option, vm) }).catch(function (err) { errorhandle(err, reject, option, vm) }) }) } // 處理響應信息 function responseInfoHandle (resInfo, resolve, reject, option, vm) { // 請求是否成功 let isSuccess = resInfo.retCode === '200' // 狀態(tài)碼 let code = resInfo.retCode // 描述信息 let message = resInfo.retMsg || '請求失??!' // 數(shù)據(jù) let resData = resInfo.data || {} if (isSuccess) { // 請求成功 console.log(`[${option.method || 'POST'}]${option.url} 請求成功!\n請求參數(shù):`, option.data, '\n響應結(jié)果:', resInfo) resolve(resData) } else { // 業(yè)務異常 console.error(`[${option.method} || 'POST']${option.url} 請求失?。n請求參數(shù):`, option.data, '\n響應結(jié)果:', resInfo) let err = new BusinessError(code, message, resData) errorhandle(err, reject, option, vm) } } // 獲取響應信息json對象 function getResponseInfo (res) { return new Promise((resolve, reject) => { // 返回的信息 let resInfo = res.data if (resInfo instanceof Blob) { const reader = new FileReader() reader.readAsText(resInfo, 'utf-8') reader.onload = () => { resInfo = JSON.parse(reader.result) resolve(resInfo) } } else { resolve(resInfo) } }) } /* 異常處理 */ function errorhandle (err, reject, option, vm) { let error = null if (err.name === 'BusinessError') { error = err } else { console.error(option.url, '請求失?。?, err.code, err) error = new SystemError(500, '非常抱歉,系統(tǒng)出現(xiàn)錯誤,請稍后重試!') } console.log('error = ', error) if (vm) { if (error.name === 'BusinessError') { // 業(yè)務異常 // 沒有權(quán)限 if (error.code === 'xxx') { error.ignore = true if (!isShowUnauthorized) { vm.$popupAlert({ title: '提示', message: '未登錄或者會話已過期,請重新登錄!', width: 330, height: 180, btnText: '重新登錄', onOK: () => { isShowUnauthorized = false // 是否顯示重新登錄彈框設為true // 跳轉(zhuǎn)到登錄頁面,登錄成功后還跳轉(zhuǎn)到原路徑 vm.$router.push({ name: 'login', params: { fromPath: vm.$route.fullPath } }) vm.$eventBus.$emit('NO_AUTH_EVENT') } }) isShowUnauthorized = true // 是否顯示重新登錄彈框設為true } error.ignore = true } else if (option.toastError !== false) { vm.$toast({ type: 'error', message: error.message }) } } else { // 系統(tǒng)異常 vm.$toast('網(wǎng)絡異常!') } } reject(error) } export default { baseUrl, http, post, get, download }
apiPlugin.js
,封裝成plugin
插件
import Vue from 'vue' import api from '@/assets/js/api.js' export default { install () { Vue.prototype.$api = api } }
main.js,注入插件
import ApiPlugin from './plugins/apiPlugin.js' // 后臺接口插件 Vue.use(ApiPlugin)
4、使用事例
4.1下載
this.$api.download({ url: '/xxx/xxx/xxx', data: params }, this)
4.2get
this.$api.get({ url: `/xxx/xxx/xx`, data: params }, this).then((res) => { console.log(res) })
4.3post
this.$api.post({ url: '/api/basicList/query', data: params }, this).then(res => { })
到這里axios的封裝基本就完成了
到此這篇關(guān)于在Vue中是如何封裝axios的文章就介紹到這了,更多相關(guān)在Vue中封裝axios內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue Element-ui input 遠程搜索與修改建議顯示模版的示例代碼
本文分為html,js和css代碼給大家詳細介紹了vue Element-ui input 遠程搜索與修改建議顯示模版功能,感興趣的朋友一起看看吧2017-10-10vue路由事件beforeRouteLeave及組件內(nèi)定時器的清除方法
今天小編就為大家分享一篇vue路由事件beforeRouteLeave及組件內(nèi)定時器的清除方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-09-09vue 使用class創(chuàng)建和清除水印的示例代碼
這篇文章主要介紹了vue 使用class創(chuàng)建和清除水印的示例代碼,幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下2020-12-12