Vue Axios请求封装
第一步:配置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 防止重复请求
在我们进行数据请求时,在上一个请求还未响应完成时,我们又发送了重复的请求,这样会造成资源损耗、性能下降,针对这样的问题,我们可以全局配置如下 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