在Vue中是如何封裝axios
更新時間:2021年10月09日 09:51:59 作者:青蓮使者
這篇文章主要介紹在Vue中是如何封裝axios的相關資料,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響應結果:', resInfo)
resolve(resData)
} else { // 業(yè)務異常
console.error(`[${option.method} || 'POST']${option.url} 請求失??!\n請求參數(shù):`, option.data, '\n響應結果:', 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è)務異常
// 沒有權限
if (error.code === 'xxx') {
error.ignore = true
if (!isShowUnauthorized) {
vm.$popupAlert({
title: '提示',
message: '未登錄或者會話已過期,請重新登錄!',
width: 330,
height: 180,
btnText: '重新登錄',
onOK: () => {
isShowUnauthorized = false // 是否顯示重新登錄彈框設為true
// 跳轉到登錄頁面,登錄成功后還跳轉到原路徑
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的封裝基本就完成了
到此這篇關于在Vue中是如何封裝axios的文章就介紹到這了,更多相關在Vue中封裝axios內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vue Element-ui input 遠程搜索與修改建議顯示模版的示例代碼
本文分為html,js和css代碼給大家詳細介紹了vue Element-ui input 遠程搜索與修改建議顯示模版功能,感興趣的朋友一起看看吧2017-10-10
vue路由事件beforeRouteLeave及組件內(nèi)定時器的清除方法
今天小編就為大家分享一篇vue路由事件beforeRouteLeave及組件內(nèi)定時器的清除方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-09-09
vue 使用class創(chuàng)建和清除水印的示例代碼
這篇文章主要介紹了vue 使用class創(chuàng)建和清除水印的示例代碼,幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下2020-12-12

