封装axios

axios怎么封装,才能提升效率?

作为前端开发者,每个项目基本都需要和后台交互,目前比较流行的ajax库就是axios了,当然也有同学选择request插件,这个萝卜白菜,各有所爱了。目前虽然axios有config、interceptor和各个请求方式,但是针对一个大型的项目,我们还是需要做二次封装才能快速提升开发效率!

今天我们针对axios库做二次封装,看看是否有简化我们的开发工作。

创建项目

vue create axios-demo

复制代码

创建目录

// 进入到项目空间中

cd axios-demo

// 在src下创建api目录

复制代码

创建三个文件(index.js/interceptor.js/request.js)

/**

* index.js

* api地址管理

*/

exportdefault{

login:'/user/login',

getInfo:'/user/getInfo'

}

复制代码

index.js实际上和axios封装没有关系,因为它也属于API这一层,所以我一起创建了,我个人习惯把项目所有url抽取到这里集中管理。

封装interceptor

interceptor作用就是拦截,可以针对请求参数和响应结果进行拦截处理,一般在项目当中,我们主要会针对接口常规报错、网络报错、系统超时、权限认证等做拦截处理。

此处我们对通过create创建实例,设置baseUrl,timeout,然后在设置request和response的拦截。

/**

* 生成基础axios对象,并对请求和响应做处理

* 前后端约定接口返回解构规范

* {

*    code:0,

*    data:"成功",

*    message:""

* }

*/

importaxiosfrom'axios'

import{ Message }from'element-ui'

// 创建一个独立的axios实例

constservice = axios.create({

// 设置baseUr地址,如果通过proxy跨域可直接填写base地址

baseURL:'/api',

// 定义统一的请求头部

headers: {

post: {

"Content-Type":"application/x-www-form-urlencoded;charset=UTF-8"

}

},

// 配置请求超时时间

timeout:10000,

// 如果用的JSONP,可以配置此参数带上cookie凭证,如果是代理和CORS不用设置

withCredentials:true

});

// 请求拦截

service.interceptors.request.use(config=>{

// 自定义header,可添加项目token

config.headers.token ='token';

returnconfig;

});

// 返回拦截

service.interceptors.response.use((response)=>{

// 获取接口返回结果

constres = response.data;

// code为0,直接把结果返回回去,这样前端代码就不用在获取一次data.

if(res.code ===0){

returnres;

}elseif(res.code ===10000){

// 10000假设是未登录状态码

Message.warning(res.message);

// 也可使用router进行跳转

window.location.href ='/#/login';

returnres;

}else{

// 错误显示可在service中控制,因为某些场景我们不想要展示错误

// Message.error(res.message);

returnres;

}

},()=>{

Message.error('网络请求异常,请稍后重试!');

});

exportdefaultservice;

复制代码

如果是CORS/JSONP需要区分环境,可通过process.env.NODE_ENV来选择使用哪个地址。 如果使用的是代理,则Vue项目需要在vue.config.js中的proxy里面增加环境判断。

process.env.NODE_ENV==="production"?"http://www.prod.com/api":"http://localhost/:3000/api"

复制代码

以上是针对interceptor做的二次封装,上面我们没有把常规错误放进去,是因为我们想要在后期控制错误是否显示,所以我们会在request中处理。

封装axios

创建request文件,针对axios做适合业务发展的封装,很多时候架构师做公共机制都是为了迎合自身项目需要,而并非一味求大做全,所以这个大家要适当调整,比如我们只用get/post请求。

/**

* request.js

* 通过promise对axios做二次封装,针对用户端参数,做灵活配置

*/

import{ Message,Loading }from'element-ui';

importinstancefrom'./interceptor'

/**

* 核心函数,可通过它处理一切请求数据,并做横向扩展

* @param {url} 请求地址

* @param {params} 请求参数

* @param {options} 请求配置,针对当前本次请求;

* @param loading 是否显示loading

* @param mock 本次是否请求mock而非线上

* @param error 本次是否显示错误

*/

functionrequest(url,params,options={loading:true,mock:false,error:true},method){

letloadingInstance;

// 请求前loading

if(options.loading)loadingInstance=Loading.service();

returnnewPromise((resolve,reject)=>{

letdata = {}

// get请求使用params字段

if(method =='get')data = {params}

// post请求使用data字段

if(method =='post')data = {data}

// 通过mock平台可对局部接口进行mock设置

if(options.mock)url='http://www.mock.com/mock/xxxx/api';

instance({

url,

method,

...data

}).then((res)=>{

// 此处作用很大,可以扩展很多功能。

// 比如对接多个后台,数据结构不一致,可做接口适配器

// 也可对返回日期/金额/数字等统一做集中处理

if(res.status ===0){

resolve(res.data);

}else{

// 通过配置可关闭错误提示

if(options.error)Message.error(res.message);

reject(res);

}

}).catch((error)=>{

Message.error(error.message)

}).finally(()=>{

loadingInstance.close();

})

})

}

// 封装GET请求

functionget(url,params,options){

returnrequest(url,params,options,'get')

}

// 封装POST请求

functionpost(url,params,options){

returnrequest(url,params,options,'post')

}

exportdefault{

get,post

}

复制代码

request.js主要针对axios做二次封装,目的同样是为了拦截所有前端请求,这样可以做前端loading效果、mock、错误拦截、错误弹框显示、数据适配、参数适配、环境适配等工作。

 

接下来,我们看下如何使用

打开main.js

// 导入插件

importrequestfrom'./api/request'

// 在原型上扩展,这样不用在每个页面都导入request

Vue.prototype.request = request;

复制代码

请求调用

this.request.get('/login',{userName:'admin',userPwd:'admin'}).then((res={})=>{

// 此处只接收成功数据,失败数据不返回

}).catch(()=>{

// catch 可以不要,如果想要捕获异常,就加上去

})

如果不做二次封装,我们很难实现以上功能点,这是在公司做了很多个中型后台系统后,总结出来的一些个人经验,我相信您看了之后,会有一些启发和帮助,如果有疑问或者不够完善可以留言或联系我,我进行修订。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335