Vue全局loading及错误提示的思路与实现
前言
近期项目马上上线,前两天产品提个需求,加个全局loading,我这半路出家的vue选手,有点懵逼,这玩意还是第一次,但是作为一个初级的前端切图仔,这个东西是必须会的,花了五分钟思考了一下,然后动键盘码出来,今天总结一下,与各位分享交流,有错误还请各位指出。
思路
我们项目请求使用的是axios,那么我们就在请求前后进行拦截,添加我们需要的东西,然后通信控制loading,通信方式我就不写了,有个老哥写的不错,可以去看看传送门
代码实现
首先对axios进行封装如果你想进行全局错误提醒也可以在拦截的代码进行操作具体代码看下面
/** *axios配置模块 *@moduleconfig *@seeutils/request */ /** *axios具体配置对象 *@description包含了基础路径/请求前后对数据对处理,自定义请求头的设置等 */ constaxiosConfig={ baseURL:process.env.RESTAPI_PREFIX, //请求前的数据处理 //transformRequest:[function(data){ //returndata //}], //请求后的数据处理 //transformResponse:[function(data){ //returndata //}], //自定义的请求头 //headers:{ //'Content-Type':'application/json' //}, //查询对象序列化函数 //paramsSerializer:function(params){ //returnqs.stringify(params) //}, //超时设置s timeout:10000, //跨域是否带Token项目中加上会出错 //withCredentials:true, //自定义请求处理 //adapter:function(resolve,reject,config){}, //响应的数据格式json/blob/document/arraybuffer/text/stream responseType:'json', //xsrf设置 xsrfCookieName:'XSRF-TOKEN', xsrfHeaderName:'X-XSRF-TOKEN', //下传和下载进度回调 onUploadProgress:function(progressEvent){ Math.round(progressEvent.loaded*100/progressEvent.total) }, onDownloadProgress:function(progressEvent){ Math.round(progressEvent.loaded*100/progressEvent.total) }, //最多转发数,用于node.js maxRedirects:5, //最大响应数据大小 maxContentLength:2000, //自定义错误状态码范围 validateStatus:function(status){ returnstatus>=200&&status<300 } //用于node.js //httpAgent:newhttp.Agent({keepAlive:true}), //httpsAgent:newhttps.Agent({keepAlive:true}) } /**导出配置模块*/ exportdefaultaxiosConfig
开始构建请求对象
constrequest=axios.create(config)
请求之前拦截
//请求拦截器 request.interceptors.request.use( config=>{ //触发loading效果 store.dispatch('SetLoding',true) returnconfig }, error=>{ returnPromise.reject(error) } )
请求后拦截
//返回状态判断(添加响应拦截器) request.interceptors.response.use( (res)=>{ //加载loading store.dispatch('SetLoding',false) //如果数据请求失败 letmessage='' letprefix=res.config.method!=='get'?'操作失败:':'请求失败:' switch(code){ case400:message=prefix+'请求参数缺失';break case401:message=prefix+'认证未通过';break case404:message=prefix+'此数据不存在';break case406:message=prefix+'条件不满足';break default:message=prefix+'服务器出错了';break } leterror=newError(message) if(tip){ errorTip(vueInstance,error,message) } letresult={...res.data,error:error} returnresult }, (error,a,b)=>{ store.dispatch('SetLoding',false) process.env.NODE_ENV!=='production'&&console.log(error) return{data:null,code:500,error:error} } )
通信
我这边通信用的是Vuex,其他方式类似
state:{ loading:0 }, mutations:{ SET_LOADING:(state,loading)=>{ loading?++state.loading:--state.loading }, CLEAN_LOADING:(state)=>{ state.loading=0 } }, actions:{ SetLoding({commit},boolean){ commit('SET_LOADING',boolean) }, CLEANLOADING({commit}){ commit('CLEAN_LOADING') } }, getters:{ loading(state){ returnstate.loading } }
state采用计数方式能够避免一个页面可能同时有多个ajax请求,导致loading闪现多次,这样就会在所有ajax都结束后才隐藏loading,不过有个很重要的地方需要注意,每一个路由跳转时无论ajax是否结束,都必须把state的值设置为0,具体下面的代码
router.beforeEach((to,from,next)=>{ store.dispatch('CLEANLOADING') next() })
全局的loading我这边是加在home.vue里,由于我这个项目是后台管理,可以加在layout.vue,其实都差不多
import{mapGetters}from'vuex' exportdefault{ data(){ } computed:{ ...mapState(['loading]) }//这个我就不写了loading样式不同我们代码也就不同
大致代码和思路就是这样可能会有错误还希望各位批评指正
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对毛票票的支持。