欢迎关注微信公众号:【 全栈攻略 】

本文主要介绍axios封装和配置项目全局loading效果

一、axios之封装 (vue版本)

1.首先 创建axios实例
    let instance = axios.create({
   		timeout: 1000 * 60,
    	baseURL: process.env.API_ROOT // 配置环境地址
    });
2.设置post请求头 默认配置(根据实际项目需求配置)
	instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
3.设置请求拦截器
	let source = CancelToken.source();
	instance.interceptors.request.use(
	    config => {
	        config.cancelToken = source.token // 取消请求
	        if(config.cancelToken && config.cancelObj && config.cancelObj.cancel) {
	            config.cancelObj.cancel('中断请求');
	            delete config.cancelObj;
	        }
	        if (!navigator.onLine) { // 断网提示
	            source.cancel('网络故障,请检查!')
	        }
	        // 配置了store持久化的就不需要取localstorage的了
	        const token = store.state.token || localStorage.getItem('token'); 
	        token && (config.headers.token = token);
	        return config;
	    },
	    error => Promise.error(error)
	)
4.设置响应拦截器
	instance.interceptors.response.use(
	    // 请求成功
	    res => {
	        if (res.headers.token) {//保存token
	            store.commit('SET_TOKEN', res.headers.token);
	              // 同理配置了store持久化的就不需要localstorage的了
	            localStorage.setItem("token", res.data.token);
	        }
	        return res.status === 200 ? Promise.resolve(res.data) : Promise.reject(res.data)
	    },
	    // 请求失败情况
	    error => {
	        const { response } = error;
	        if (response) {
	            // 请求已发出,但是不在2xx的范围 
	            errorHandle(response.status, response.data.message);
	            return Promise.reject(response);
	        } else {
	            // 处理其他的情况
	            if (error.message) { // 取消请求的message
	                tip(error.message)
	            } else {
	                tip('服务故障,请检查!')
	            }
	            return Promise.resolve() 
	        }
	    });
5.最后导出axios的实例,至此axios的简单封装就完成了,需要项目特殊处理的可以各自拓展。从第1点到第5点复制下来就是一个完整的axios封装文件了,就不画蛇添足把整个文件粘贴出来了。
	export default instance;

二、配置项目全局loading效果(本文以element-ui为例,其它UI框架一样,只是API不一样而已)

1.首先引入element 的loading模块
	import { Loading } from "element-ui";
2.定义一个请求次数的变量,用来记录当前页面总共请求的次数
	let loadingRequestCount = 0;
3.编写一个显示loading的函数 并且记录请求次数 ++
	const showLoading = () => {
		    if (loadingRequestCount === 0) {
		           // element的服务方式 target 我这边取的是表格 项目是后台系统 每个页面都有表格 类似整个表格loading
		              和在表格配置v-loading一样的效果,这么做是全局实现了,不用每个页面单独去v-loading
		        loadingInstance = Loading.service({ target: '.el-table'});
		    }
		    loadingRequestCount++
	  }

target参数详解

4.编写一个隐藏loading的函数,并且记录请求次数
	const hideLoading = () => {
	    if (loadingRequestCount <= 0) return
	    loadingRequestCount--
	    if (loadingRequestCount === 0) {
	        vue.$nextTick(()=>{//以服务的方式调用的 Loading 需要异步关闭
	              loadingInstance.close();
	        });
	    }
	 }
5.接下来就是把这两个函数分别在请求拦截和响应拦截里调用即可
	   // 请求拦截
		let source = CancelToken.source();
		instance.interceptors.request.use(
		    config => {
		        config.cancelToken = source.token // 取消请求
		        if(config.cancelToken && config.cancelObj && config.cancelObj.cancel) {
		            config.cancelObj.cancel('中断请求');
		            delete config.cancelObj;
		        }
		        if (!navigator.onLine) { // 断网提示
		            source.cancel('网络故障,请检查!')
		        }
		        
		        // 请求拦截进来调用显示loading效果
		         showLoading(config)
		         
		        // 配置了store持久化的就不需要取localstorage的了
		        const token = store.state.token || localStorage.getItem('token'); 
		        token && (config.headers.token = token);
		        return config;
		    },
		    error => Promise.error(error)
		)
		
	  	instance.interceptors.response.use(
		   // 请求成功
		    res => {
		    
		      // 响应拦截进来隐藏loading效果,此处采用延时处理是合并loading请求效果,避免多次请求loading关闭又开启
		      合并loading请求效果 避免重复请求
		      
				setTimeout(() => {
		            hideLoading()
		        }, 200);
		        
		        if (res.headers.token) {//保存token
		            store.commit('SET_TOKEN', res.headers.token);
		              // 同理配置了store持久化的就不需要localstorage的了
		            localStorage.setItem("token", res.data.token);
		        }
		        return res.status === 200 ? Promise.resolve(res.data) : Promise.reject(res.data)
		    },
		    // 请求失败情况
		    error => {
		      // 响应拦截进来隐藏loading效果,此处采用延时处理是合并loading请求效果,避免多次请求loading关闭又开启
		      合并loading请求效果 避免重复请求
		      
			    setTimeout(() => {
	         	   hideLoading()
	      		 }, 200);
	      		 
		        const { response } = error;
		        if (response) {
		            // 请求已发出,但是不在2xx的范围 
		            errorHandle(response.status, response.data.message);
		            return Promise.reject(response);
		        } else {
		            // 处理其他的情况
		            if (error.message) { // 取消请求的message
		                tip(error.message)
		            } else {
		                tip('服务故障,请检查!')
		            }
		            return Promise.resolve() 
		      }
		  });
至此本文结束,如有不当,欢迎指正。
Logo

前往低代码交流专区

更多推荐