第一步:配置axios
首先,创建一个tools.js,这里面存放的是接口配置、请求出错和当前环境配置,我平常elementUI用的比较多,这里你也可以使用自己的UI库。
import {
Message
} from 'element-ui';
//判断当前环境
let env = window.location.href.includes('test') ? "test" :
(window.location.href.includes('me-web-test') || window.location.href.includes('localhost')
|| window.location.href.includes('192.168') || window.location.href.includes('127.0.0.1')) ? "develop" : "production";
const Conts = {
env,
domain: (env === 'develop') ? `测试接口1` : (env === 'test') ? `测试接口2` : `生产接口`,
popupTime: 1000,
popupTimes: [500, 1000, 1500, 2000, 2500, 3000, 3500, 4000, 4500, 5000],
};
/**
* @description 通用提示
*/
const Alert = {
//fetch 错误提示
permissionError(option) {
let _status = option.data.status || option.data.response.status;
let _mes = option.data.response.data.message;
if (_status === 400) {
let newMes = '';
if (Object.keys(option.data.response.data.data).length !== 0) {
for (let item in option.data.response.data.data) {
if (newMes !== '') {
newMes += `;${option.data.response.data.data[item]}`;
} else {
newMes += `${option.data.response.data.data[item]}`;
}
}
}
_mes = newMes ? newMes : _mes ? _mes : '参数错误,请稍后重试。';
option.cb = (typeof option.cb === 'function') ? option.cb : function () {};
if (option.popup) {
Message({
message: _mes,
type: 'error',
duration: Conts.popupTimes[6],
}).then(() => {
option.cb();
});
} else {
option.cb();
}
} else if (_status === 401) {
if (option.cb) {
option.cb();
}
} else if (_status === 403) {
_mes = _mes ? _mes : '您没有权限';
option.cb = (typeof option.cb === 'function') ? option.cb : function () {};
option.popup = (typeof option.popup === 'boolean') ? option.popup : true;
if (option.popup) {
Message({
message: _mes,
type: 'error',
duration: Conts.popupTimes[6],
}).then(() => {
option.cb();
});
} else {
option.cb();
}
} else if (_status === 429) {
_mes = _mes ? _mes : '您尝试太多次啦,请稍后再试。';
option.cb = (typeof option.cb === 'function') ? option.cb : function () {};
option.popup = (typeof option.popup === 'boolean') ? option.popup : true;
if (option.popup) {
Message({
text: _mes,
type: 'error',
duration: Conts.popupTimes[6],
}).then(() => {
option.cb();
});
} else {
option.cb();
}
} else if (_status === 404) {
_mes = _mes ? _mes : '页面丢失';
option.cb = (typeof option.cb === 'function') ? option.cb : function () {};
option.popup = (typeof option.popup === 'boolean') ? option.popup : true;
if (option.popup) {
Message({
message: _mes,
type: 'error',
duration: Conts.popupTimes[6],
}).then(() => {
option.cb();
});
} else {
option.cb();
}
} else {
console.warn(`其他错误码:${_status}`)
}
},
};
export default {
Conts,
Alert
}
第二步:引用tools.js
在main.js中全局引用以及axios配置拦截器等
import Vue from 'vue'
import axios from 'axios'
import tools from './js/vuex/tools' // 全局定义接口变量
Vue.prototype.$axios = axios
Vue.prototype.$Tools = tools
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 对响应数据做点什么
if (response.data.message == "您没有获得授权") {
Message({
type: 'warning',
message: '您没有获得授权,请重新登录'
});
router.push({
name: "loginnew"
})
}
return response;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
第三步:使用
在需要的页面进行接口请求
//account:请求的接口
//params:参数
this.$axios
.post(`${this.$Tools.Conts.domain}account`, params)
.then(res => {
//请求成功
if (res.data) {
if (res.data.code === 0) {
this.$message({
type: "success",
message: res.data.message
});
} else {
this.$message({
type: "warning",
message: res.data.message
});
}
}
})
.catch(err => {
//请求失败
this.$Tools.Alert.permissionError({
data: err,
popup: true
});
});
在我们进行数据请求时,在上一个请求还未响应完成时,我们又发送了重复的请求,这样会造成资源损耗、性能下降,针对这样的问题,我们可以全局配置如下 axios 请求
import axios from "axios";
/**
* @description 函数返回唯一的请求key **/
function getRequestKey(config) {
let {
method,
url,
params,
data
} = config;
// 参数相同时阻止重复请求:防止用户重复提交数据
return [method, url, JSON.stringify(params), JSON.stringify(data)].join("&");
}
/**
* @description 添加请求信息 **/
let pendingRequest = new Map();
function addPendingRequest(config) {
let requestKey = getRequestKey(config);
config.cancelToken = config.cancelToken || new axios.CancelToken((cancel) => {
if (!pendingRequest.has(requestKey)) {
pendingRequest.set(requestKey, cancel);
}
});
}
/**
* @description 取消重复请求,移除重复请求信息 **/
function removePendingRequest(config) {
let requestKey = getRequestKey(config);
if (pendingRequest.has(requestKey)) {
// 重复请求时调用该函数
let cancel = pendingRequest.get(requestKey);
cancel(requestKey);
// 删除上一次接口请求
pendingRequest.delete(requestKey);
}
}
/**
* @description 请求拦截器 **/
axios.interceptors.request.use(
function (config) {
// 取消重复请求,移除重复请求信息
removePendingRequest(config);
// 把当前请求信息添加到pendingRequest对象中
addPendingRequest(config);
return config;
},
function (error) {
return Promise.reject(error);
}
);
/**
* @description 响应拦截器**/
axios.interceptors.response.use(
function (response) {
removePendingRequest(response.config);
return response;
},
function (error) {
removePendingRequest(error.config || {});
if (axios.isCancel(error)) {
//取消重复请求
console.log(error.message);
} else {
console.log('异常处理')
}
return Promise.reject(error);
}
);
export default axios