vue使用axios的小技巧分享
作者:落笔忆梦
这篇文章主要为大家详细介绍了一些vue使用axios的小技巧,文中的示例代码讲解详细,对我们深入掌握vue有一定的帮助,感兴趣的小伙伴可以跟随小编一起学习一下
全局loading
在日常开发工作中,每次使用api
请求数据时,都会涉及添加loading
状态,从而达到优化用户体验的效果,特别是对于请求时间较长的接口时。这样每次请求开始时就要添加loading
状态,请求完成时要移除loading
状态,导致重复又繁琐的工作。所以我们可以思考从axios方向着手,嘻嘻嘻...
思路
创建axios函数 我们采用axios.create()
创建http
方法
/** * Axios实例化参数选项对象 * @const * @type {object} * @property {object} headers 请求头对象对象,默认:null * @property {number} timeout 超时时间,默认:0, 不限制 * @property {boolean} withCredentials 是否带上验证信息, 默认:true * @property {number} maxContentLength 限制最大发送内容长度,默认:-1 不限制 * @property {strin} baseURL 默认请求拼接的前缀 */ const http = axios.create({ headers: { 'Content-Type': 'application/json;charset=UTF-8', // ie浏览器get请求兼容问题 'Cache-Control': 'no-cache', 'If-Modified-Since': '0' }, timeout: 0, withCredentials: false, responseType: 'json', maxContentLength: -1, baseURL: import.meta.env.VITE_APP_BASE_API }); export default http
添加loading
axios具有请求拦截器以及响应拦截器的特性进行处理。我们在请求拦截器触发时添加loading
,响应拦截器触发时移除loading
。
import { ElLoading } from 'element-plus'; // 全局loading let loadingInstance; /** * Axios实例化参数选项对象 * @const * @type {object} * @property {object} headers 请求头对象对象,默认:null * @property {number} timeout 超时时间,默认:0, 不限制 * @property {boolean} withCredentials 是否带上验证信息, 默认:true * @property {number} maxContentLength 限制最大发送内容长度,默认:-1 不限制 * @property {strin} baseURL 默认请求拼接的前缀 */ const http = axios.create({ headers: { 'Content-Type': 'application/json;charset=UTF-8', // ie浏览器get请求兼容问题 'Cache-Control': 'no-cache', 'If-Modified-Since': '0' }, timeout: 0, withCredentials: false, responseType: 'json', maxContentLength: -1, baseURL: import.meta.env.VITE_APP_BASE_API }); /** * 请求拦截器 */ http.interceptors.request.use((config) => { // 创建全局loading loadingInstance = ElLoading.service({ text: '加载中...', target: '#ContentArea' }); return config; }); // 响应拦截器 http.interceptors.response.use((res) => { nextTick(() => { loadingInstance?.close(); }); }); export default http
注意
这个时候乍一看是没有什么问题的,但是当多个请求同时执行时,每个请求都会添加全局loading
,当第一个请求完成时全局loading
就被移除了,实际上应该是最后一个请求完成时,才移除全局loading
。
处理loading
混乱 基于loading
的拦截器,我们可以定义一个请求队列,对当前正在进行中的请求进行管理,在请求拦截器中将该请求添加进请求队列中,当请求队列的长度为0时,添加loading
,在响应拦截器中将该请求从请求队列中移除,当请求队列的长度为0时,移除loading
。
import { ElLoading } from 'element-plus'; // 请求队列 const httpPromiseArr = new Map(); // 全局loading let loadingInstance; /** * 判断是否为JSON格式 * @param {*} str * @returns */ function isJSON(str) { if (typeof str == 'string') { try { JSON.parse(str); return true; } catch (e) { return false; } } } /** * 创建缓存key, 由请求url、类型、参数、发送数据构成的标识符 * @param {string} url 请求url * @param {string} type 请求类型 * @param {object} params url参数对象 * @param {object} data 请求数据 * @return {string} */ function createKey(config) { const { url, method, params = {}, data = {} } = config; return encodeURIComponent( [url, method, isJSON(params) ? params : JSON.stringify(params), isJSON(data) ? data : JSON.stringify(data)].join( ',' ) ); } /** * Axios实例化参数选项对象 * @const * @type {object} * @property {object} headers 请求头对象对象,默认:null * @property {number} timeout 超时时间,默认:0, 不限制 * @property {boolean} withCredentials 是否带上验证信息, 默认:true * @property {number} maxContentLength 限制最大发送内容长度,默认:-1 不限制 * @property {strin} baseURL 默认请求拼接的前缀 */ const http = axios.create({ headers: { 'Content-Type': 'application/json;charset=UTF-8', // ie浏览器get请求兼容问题 'Cache-Control': 'no-cache', 'If-Modified-Since': '0' }, timeout: 0, withCredentials: false, responseType: 'json', maxContentLength: -1, baseURL: import.meta.env.VITE_APP_BASE_API }); /** * 请求拦截器 */ http.interceptors.request.use((config) => { if (httpPromiseArr.size === 0) { // 创建全局loading loadingInstance = ElLoading.service({ text: '加载中...' }); } httpPromiseArr.set(createKey(config)); return config; }); // 响应拦截器 http.interceptors.response.use((res) => { const key = createKey(res.config); if (httpPromiseArr.has(key)) { httpPromiseArr.delete(key); } // 全部请求结束关闭loading if (httpPromiseArr.size === 0) { nextTick(() => { loadingInstance?.close(); }); } }); export default http
总结
思路就是使用队列来管理请求的方式来实现,基于此思路同样可以完成,在同一时间内禁止同意请求的多次触发,也就是拦截同一请求,进行性能优化。
到此这篇关于vue使用axios的小技巧分享的文章就介绍到这了,更多相关vue使用axios内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!