详解vue中axios请求的封装
axios
Axios是一个基于promise的HTTP库,可以用在浏览器和node.js中,也是vue官方推荐使用的http库;封装axios,一方面为了以后维护方便,另一方面也可以对请求进行自定义处理
安装
npmiaxios
封装
我把axios请求封装在http.js中,重新把get请求,post请求封装了一次
首先,引入axios
importaxiosfrom'axios'
设置接口请求前缀
一般我们开发都会有开发、测试、生产环境,前缀需要加以区分,我们利用node环境变量来作判断,
if(process.env.NODE_ENV==='development'){ axios.defaults.baseURL='http://dev.xxx.com' }elseif(process.env.NODE_ENV==='production'){ axios.defaults.baseURL='http://prod.xxx.com' }
在localhost调试时,直接用开发地址一般都会有跨域的问题,所以我们还需要配置代理
本项目是vuecli3搭建的,代理配置是在vue.config.js文件中:
module.exports={ devServer:{ proxy:{ '/proxyApi':{ target:'http://dev.xxx.com', changeOrigin:true, pathRewrite:{ '/proxyApi':'' } } } } }
这样就成功把/proxyApi指向了'http://dev.xxx.com',重启服务
修改一下http.js中的配置
if(process.env.NODE_ENV==='development'){ axios.defaults.baseURL='/proxyApi' }elseif(process.env.NODE_ENV==='production'){ axios.defaults.baseURL='http://prod.xxx.com' }
拦截器
接着设置超时时间和请求头信息
axios.defaults.timeout=10000 //请求头信息是为post请求设置 axios.defaults.headers.post['Content-Type']='application/x-www-form-urlencoded;charset=UTF-8'
axios很好用,其中之一就是它的拦截器十分强大,我们就可以为请求和响应设置拦截器,比如请求拦截器可以在每个请求里加上token,做了统一处理后维护起来也方便,响应拦截器可以在接收到响应后先做一层操作,如根据状态码判断登录状态、授权。
//请求拦截器 axios.interceptors.request.use( config=>{ //每次发送请求之前判断是否存在token //如果存在,则统一在http请求的header都加上token,这样后台根据token判断你的登录情况,此处token一般是用户完成登录后储存到localstorage里的 token&&(config.headers.Authorization=token) returnconfig }, error=>{ returnPromise.error(error) }) //响应拦截器 axios.interceptors.response.use(response=>{ //如果返回的状态码为200,说明接口请求成功,可以正常拿到数据 //否则的话抛出错误 if(response.status===200){ if(response.data.code===511){ //未授权调取授权接口 }elseif(response.data.code===510){ //未登录跳转登录页 }else{ returnPromise.resolve(response) } }else{ returnPromise.reject(response) } },error=>{ //我们可以在这里对异常状态作统一处理 if(error.response.status){ //处理请求失败的情况 //对不同返回码对相应处理 returnPromise.reject(error.response) } })
getpost的封装
httpGet:一个参数是请求的url,一个就携带的请求参数,返回promise对象
//get请求 exportfunctionhttpGet({ url, params={} }){ returnnewPromise((resolve,reject)=>{ axios.get(url,{ params }).then((res)=>{ resolve(res.data) }).catch(err=>{ reject(err) }) }) }
httpPost:原理和get差不多,需要注意,这里多了个data参数,post请求提交前需要对它进行序列号操作,这里是通过transformRequest做处理;另外两个参数url,params和get请求的一样;
//post请求 exportfunctionhttpPost({ url, data={}, params={} }){ returnnewPromise((resolve,reject)=>{ axios({ url, method:'post', transformRequest:[function(data){ letret='' for(letitindata){ ret+=encodeURIComponent(it)+'='+encodeURIComponent(data[it])+'&' } returnret }], //发送的数据 data, //url参数 params }).then(res=>{ resolve(res.data) }) }) }
如何使用
我把所有的接口调用都在api.js文件中
先引入封装好的方法,再在要调用的接口重新封装成一个方法暴露出去
import{httpGet,httpPost}from'./http' exportconstgetorglist=(params={})=>httpGet({url:'apps/api/org/list',params})
在页面中可以这样调用:
//.vue import{getorglist}from'@/assets/js/api' getorglist({id:200}).then(res=>{ console.log(res) })
这样可以把api统一管理起来,以后维护修改只需要在api.js文件操作即可。
完整代码
最后贴上完整代码
//http.js importaxiosfrom'axios' //环境的切换 if(process.env.NODE_ENV==='development'){ axios.defaults.baseURL='/proxyApi' }elseif(process.env.NODE_ENV==='production'){ axios.defaults.baseURL='http://prod.xxx.com' } //请求拦截器 axios.interceptors.request.use( config=>{ token&&(config.headers.Authorization=token) returnconfig }, error=>{ returnPromise.error(error) }) axios.defaults.timeout=10000 axios.defaults.headers.post['Content-Type']='application/x-www-form-urlencoded;charset=UTF-8' //响应拦截器 axios.interceptors.response.use(response=>{ if(response.status===200){ if(response.data.code===511){ //未授权调取授权接口 }elseif(response.data.code===510){ //未登录跳转登录页 }else{ returnPromise.resolve(response) } }else{ returnPromise.reject(response) } },error=>{ //我们可以在这里对异常状态作统一处理 if(error.response.status){ //处理请求失败的情况 //对不同返回码对相应处理 returnPromise.reject(error.response) } }) //get请求 exportfunctionhttpGet({ url, params={} }){ returnnewPromise((resolve,reject)=>{ axios.get(url,{ params }).then((res)=>{ resolve(res.data) }).catch(err=>{ reject(err) }) }) } //post请求 exportfunctionhttpPost({ url, data={}, params={} }){ returnnewPromise((resolve,reject)=>{ axios({ url, method:'post', transformRequest:[function(data){ letret='' for(letitindata){ ret+=encodeURIComponent(it)+'='+encodeURIComponent(data[it])+'&' } returnret }], //发送的数据 data, //url参数 params }).then(res=>{ resolve(res.data) }) }) }
//api.js import{httpGet,httpPost}from'./http' exportconstgetorglist=(params={})=>httpGet({url:'apps/api/org/list',params}) exportconstsave=(data)=>{ returnhttpPost({ url:'apps/wechat/api/save_member', data }) }
//.vue
为什么还要多封装一层promise,不直接返回axios。
我在这里统一做个说明:
当然可以直接返回axios.get().then(res=>res.data),写法更简洁些;个人编程习惯,感觉resolve(res.data)写法更优雅些,这个就见仁见智了,所以正文对这点先做保留。这篇笔记也是提供一个思路,仅供参考。小伙伴可以根据自己实际业务需求来选择。
以上所述是小编给大家介绍的vue中axios请求的封装详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!