不不不,原来有些人已经2021年了,连TypeScript都没听说过吧?虽然在项目中使用TypeScript短期内会增加一些开发成本,但是对于需要长期维护的项目,TypeScript可以降低其维护成本,使用TypeScript可以增加代码的可读性和可维护性,并且拥有相对活跃的社区,等到大前端的趋势了,就开始吧~用TypeScript封装axios基础库代码如下://http.tsimportaxios,{AxiosRequestConfig,AxiosResponse}from'axios'import{ElMessage}from"element-plus"constshowStatus=(status:number)=>{letmessage=''switch(status){case400:message='请求错误(400)'breakcase401:message='未授权,请登录再次(401)'breakcase403:message='AccessDenied(403)'breakcase404:message='RequestError(404)'breakcase408:message='RequestTimedOut(408)'breakcase500:消息='服务器错误(500)'breakcase501:message='ServiceNotImplemented(501)'breakcase502:message='NetworkError(502)'breakcase503:message='ServiceUnavailable(503)'breakcase504:message='Networktimeout(504)'breakcase505:message='不支持HTTP版本(505)'布雷亚kdefault:message=`Connectionerror(${status})!`}return`${message},请检查网络或联系管理员!`}constservice=axios.create({//联合调试//baseURL:process.env.NODE_ENV==='production'?`/`:'/api',baseURL:"/api",headers:{get:{'Content-Type':'application/x-www-form-urlencoded;charset=utf-8'},post:{'Content-Type':'application/json;charset=utf-8'}},//跨站访问控制请求withCredentials:true,timeout:30000,transformRequest:[(data)=>{data=JSON.stringify(data)returndata}],validateStatus(){//使用async-await,processreject的情况比较复杂,所以全部返回resolve,在业务代码中处理异常returntrue},transformResponse:[(data)=>{if(typeofdata==='string'&&data.startsWith('{')){data=JSON.parse(data)}returndata}]})//请求拦截器service.interceptors.request.use((config:AxiosRequestConfig)=>{//获取token并添加到请求中headerlettoken=localStorage.getItem('token')if(token){config.headers.Authorization=`${token}`;}returnconfig},(error)=>{//将错误抛给业务代码error.data={}error.data.msg='服务器异常,请联系管理员!'returnPromise.resolve(error)})//响应拦截器service.interceptors.response.use((response:AxiosResponse)=>{conststatus=response.statusletmsg=''if(status<200||status>=300){//处理http错误,抛给业务代码msg=showStatus(status)if(typeofresponse.data==='string'){response.data={msg}}else{response.data.msg=msg}}returnresponse},(error)=>{if(axios.isCancel(error)){console.log('repeatedrequest:'+error.message)}else{//处理错误代码//错误抛出到业务代码error.data={}error.data.msg='请求超时或服务器异常,请检查网络或联系管理员!'ElMessage.error(error.data.msg)}returnPromise.reject(error)})exportdefaultservice取消多次重复的请求版本在上面的代码中添加如下代码://http.tsimportaxios,{AxiosRequestConfig,AxiosResponse}from'axios'importqsfrom"qs"import{ElMessage}from“element-plus"//声明一个Map来存放每个请求的标识和取消函数constpending=newMap()/***addrequest*@param{Object}config*/constaddPending=(config:AxiosRequestConfig)=>{consturl=[config.method,config.url,qs.stringify(config.params),qs.stringify(config.data)].join('&')config.cancelToken=config.cancelToken||newaxios.CancelToken(cancel=>{if(!pending.has(url)){//如果当前没有pending请求,则添加pending.set(url,cancel)}})}/***移除请求*@param{Object}config*/constremovePending=(config:AxiosRequestConfig)=>{consturl=[config.method,config.url,qs.stringify(config.params),qs.stringify(config.data)]。join('&')if(pending.has(url)){//如果当前有requestID处于pending中,则需要取消当前请求并移除constcancel=pending.get(url)cancel(url)pending.delete(url)}}/***清除挂起的请求(路由跳转时调用)*/exportconstclearPending=()=>{for(const[url,cancel]ofpending){cancel(url)}pending.clear()}//请求拦截器service.interceptors.request.use((config:AxiosRequestConfig)=>{removePending(config)//请求开始前,检查之前的请求取消操作addPending(config)//将当前请求添加到挂起lettoken=localStorage.getItem('token')if(token){config.headers.Authorization=`${token}`;}returnconfig},(error)=>{//错误被抛给业务代码error.data={}error.data.msg='服务器异常,请联系管理员!'returnPromise.resolve(error)})//响应拦截器service.interceptors.response.use((response:AxiosResponse)=>{removePending(response)//请求结束后,移除本次请求conststatus=response.statusletmsg=''if(status<200||status>=300){//处理http错误并抛给业务代码,(error)=>{if(axios.isCancel(error)){console.log('repeatedrequest:'+error.message)}else{//处理错误代码//抛出的错误业务代码error.data={}error.data.msg='请求超时或服务器异常,请检查网络或联系管理员!'ElMessage.error(error.data.msg)}returnPromise.reject(error)})export默认服务在路由跳转时撤销所有请求在路由文件index.tsvue-中添加import{createRouter,createWebHistory,RouteRecordRaw}from'router'importLoginfrom'@/views/Login/Login.vue'//引入axios中暴露的clearPending函数import{clearPending}from"@/api/axios"..........constrouter=createRouter({history:createWebHistory(process.env.BASE_URL),routes})router.beforeEach((to,from,next)=>{//在跳转到路由之前,清除所有请求clearPending()//...next()})exportdefaultrouter使用封装的axios请求库封装响应格式//接口通过格式响应exportinterfaceHttpResponse{status:numberstatusText:stringdata:{code:numberdesc:string[key:string]:any}}封装接口方法举个栗子,封装User接口,代码如下~importAxiosfrom'./axios'import{HttpResponse}from'@/@types'/***@interfaceloginParams-登录参数*@property{string}username-用户名*@property{string}password-用户密码*/interfaceLoginParams{username:stringpassword:string}//封装User类型的接口方法exportclassUserService{/***@description查询用户信息*@param{number}teamId-要查询的团队ID*@返回{HttpResponse}结果*/staticasynclogin(params:LoginParams):Promise
