当前位置: 首页 > Web前端 > vue.js

Vue项目中API接口和axios请求的封装

时间:2023-03-31 22:34:57 vue.js

在实际项目中,与后台的数据交互是必不可少的。我平时用的都是axios库,所以下面的例子也是基于axios封装的。如果你对axios不了解,请看这里的axios文档1.安装首先是npm。安装axios很简单:npminstallaxios2.没有封装的问题如果你在一个没有封装接口的项目中,你可以看到文件中到处都是这样的接口调用方法:this.$axios.post("/user/add",{params:{name:this.name,age:this.age}}).then(res=>{console.log(res)}).then(err=>{console.log(err)})不是不可以这样写,但是有一些缺陷。接口请求的url分散在各个文件中。如果需要在接口调用成功或失败时做一些处理,则需要对每个文件进行更改。因此,这些接口请求是统一的、集中的。如果有调整,直接在集中文件中查找修改即可,不用逐个文件检查。3、创建文件首先在项目的src目录下,新建文件夹和文件目录结构如下:├──src源代码目录│├──apis接口文件目录││├──login.api.js登录模块接口api││└──user.api.js用户模块接口api│├──服务请求相关文件目录││├──address.js请求地址配置文件││└──request.jsaxiospackage,requestinterception,responsecode处理等操作的api接口文件模块的划分可以根据你的实际项目按照业务功能或者业务逻辑或者其他形式来划分。4、请求地址配置一般我们项目中会有多个项目环境,少的话会有开发环境和生产环境。一般情况下,开发环境和生产模式会有不同的baseURL,所以我们需要根据不同的环境切换不同的baseURL。address.jsfile://根据process.env.NODE_ENV在不同的baseURL之间切换constisPro=process.env.NODE_ENV==='production'module.exports={//'apis':在vue.config中由代理设置.js代理baseURL:isPro?'http://192.168.100.120/ceds':'/apis'}5.axios配置(设置请求头、响应码处理)的大致思路是封装一个请求类,里面包含get、post等request方法,这些请求方法会调用request方法,调用传入不同参数的原始axios请求,然后返回一个Promise。request.js文件:importaxiosfrom'axios'importQsfrom'qs'importVuefrom'vue'import{getToken}from'@Utils/session.utils'//storeandgettokenfileimportaddressfrom'./address'//请求地址classRequest{constructor(){//创建一个axios实例this._axios=axios.create({baseURL:address.baseURL,timeout:1000*5,//请求超时headers:{}})//请求拦截this._axios.interceptors.request.use(config=>{constrequestHeader={'X-Requested-With':'XMLHttpRequest','Content-Type':'application/json;charset=UTF-8','Access-Control-Allow-Origin':'*',token:getToken()//统一在请求头添加token}config.headers=Object.assign(config.headers,requestHeader)returnconfig},error=>{承诺.reject(错误)})}//根据请求方式,判断参数是放在query还是body//最直观的区别,比如GET请求是在url中包含参数,而POST是通过请求body把参数放在body中,所以在提交的时候参数的形式是有区别的//下面列出四种你可以自行调整常用请求方式的参数形式/***发送get请求*@param{String}url地址*@param{Object}query查询参数*@returnjson数据*/get(url,query={}){returnthis._request('get')(url,{...query})}/***发送post请求*@param{String}url地址*@param{Object}body查询参数*@返回json数据*/post(url,body={},headers){让数据if(this.isFormData(body)){data=body}elseif(Array.isArray(body)){data=body}else{data={...body}}returnthis._request('post')(url,headers)(url,data)}put(url,body={}){returnthis._request('put')(url,{...body})}delete(url,body={}){returnthis._request('delete')(url,{...body})}是FormData=v=>{returnObject.prototype.toString.call(v)==='[objectFormData]'}/***设置请求头*@param{Object}header请求头*/setHeaders(header){Object.keys(header).forEach(key=>{this._axios.defaults.headers[key]=header[key]})}//处理请求头handleHeaders(){constheaders={}headers['XMIME-TYPE']='3'Headers['Content-Type']='application/json;charset=UTF-8'returnheaders}/***sendrequest*@param{String}method请求方法类型*@paramheaders*@returns{function(*=,*=):Promise}*@private*/_request(method,headers){this.setHeaders(this.handleHeaders())//设置统一的请求头if(headers){this.setHeaders(headers)//自定义请求头}return(url,data,timeout)=>{constconfig={url,方法,超时:超时||this._axios.defaults.timeout}//构造请求配置//确定请求类型getpostconstparamType=['get','delete'].indexOf(method)!==-1?'params':'data'config[paramType]=data//参数序列化config.paramsSerializer=params=>{returnQs.stringify(params,{arrayFormat:'repeat'})}returnnewPromise((resolve,reject)=>{//发送真实请求,验证权限,检查404等状态this._axios.request(config).then(response=>{if(this.handleSuccessStatus(response.data.code,response.data)){if(response.headers['content-type']!=='text/plain;charset=urf-8'){resolve(//将响应结果包装两次Object.assign({success:Number(response.data.code)===200,data:response.data.data,msg:response.data.msg},response.data))//处理返回结果}else{resolve(response.data)}}},response=>{//处理错误码if(response.response){conststatusCode=response.response.statusthis.handleErrorStatus(statusCode)}else{Vue.prototype.$message.error(response.信息)}reject(response)}).catch(err=>{reject(err)})})}}}//请求成功,返回错误码//具体状态码与后台开发者统一,然后根据状态码给出相应的提示//下面是我在项目中的操作,可以调整扩展handleSuccessStatus(code,data){letresult=''letflag=falseswitch(code){case'20007':result='未找到二次验证密码!'flag=truebreakcase'20008':result='您的二次认证密码未修改,请先修改!'flag=truebreakcase'20009':result='您没有开启二次认证,请联系管理员!'flag=truebreakcase'90001':result='请输入二次认证密码!'flag=truebreakcase'90002':result='无操作权限!'flag=true打破默认:break}//进行通知//$message方法是我按需引入的element-ui中的提示组件,你可以换成自己的提示组件if(result){Vue.prototype.$message.error(result)}returnflag}//根据错误码获取错误信息handleErrorStatus(statusCode){leterrorMsg=''if(statusCode===500){errorMsg='数据请求失败,请联系管理员!'}elseif(statusCode===404){errorMsg='请求地址错误!'}elseif(statusCode===402){errorMsg='当前您没有操作该数据的权限!'}else{errorMsg='请求错误!'}//NotifyVue.prototype.$message.error(errorMsg)}}exportdefaultnewRequest()6.在接口管理文件中,我们调用上面封装的request类,传入相应的参数user.api.js文件:importhttpfrom'../services/request'/***@descriptiongetuserlist*@param{*}params请求接口参数*///这里定义的reqUserList方法会调用在我们封装的请求中获取方法。get方法第一个参数是请求地址,第二个参数是查询参数方法并传入参数。import{reqUserList}from'@Apis/user.api'//importapiexportdefault{name:'UserList',......created(){},methods:{asyncgetUsers(){//调用api接口并传入参数constres=awaitreqUserList({page:1,size:10})console.log(res)//获取响应结果}}}这样,接口的封装和基本使用就是完全的。PS:以上文件名、文件夹名、方法名、路径等都是我自己获取的,大家可以根据自己的代码风格习惯进行调整。以上是我在项目中的一些写法,有些地方可能不够完善,如有疑问,请指正,谢谢:)