小马厂网站建设,仿站定制模板建站,网站大全全部免费,成都口碑最好的家装公司优化基于axios接口管理的骚操作#xff01; 本文针对中大型的后台项目的接口模块优化#xff0c;在不影响项目正常运行的前提下#xff0c;增量更新。 强化功能
1.接口文件写法简化#xff08;接口模块半自动化生成#xff09; 2.任务调度、Loading调度#xff08;接口层…优化基于axios接口管理的骚操作 本文针对中大型的后台项目的接口模块优化在不影响项目正常运行的前提下增量更新。 强化功能
1.接口文件写法简化接口模块半自动化生成 2.任务调度、Loading调度接口层面的防抖兜底多个接口共用一个loading防止闪烁 3.接口提示自由化提示消息可由前端控制也可以由后端控制
接口文件写法简化 对于一些中后台模块的接口基本上都是增删改查以及审核流的一些功能(其他特殊接口暂且不谈)。如果后端接口足够规范的话大概就是下面这个情形 import request from /utils/request;
// 销售退货列表
export function getSalesReturnList(data) {return request({url: /sales_return/list,method: post,data,});
}
// 保存销售退货
export function saveSalesReturn(data) {return request({url: /sales_return/save,method: post,data,});
}
// 根据Id获取销售退货
export function getSalesReturn(query) {return request({url: /sales_return/get,method: get,params: query,});
}
// 根据Id删除销售退货
export function deleteSalesReturn(data) {return request({url: /sales_return/delete,method: post,data,});
}
// 提交销售退货审核
export function submitSalesReturn(data) {return request({url: /sales_return/submit,method: post,data,});
}
// 审核销售退货
export function auditSalesReturn(data) {return request({url: /sales_return/audit,method: post,data,});
}
// 撤审销售退货
export function revokeAuditSalesReturn(data) {return request({url: /sales_return/withdraw,method: post,data,});
}
// 审核拒绝销售退货
export function rejectSalesReturn(data) {return request({url: /sales_return/reject,method: post,data,});
}
// 作废销售退货
export function discardSalesReturn(data) {return request({url: /sales_return/discard,method: post,data,});
} 我觉得这个也太重复了而且接口函数命名太麻烦了要让团队规范起来比较困难。能不能自动生成了命名也帮忙处理了这样这种接口文件岂不是更加规范。
接下来想想办法
假设如上一个单据模块的通常来说有九个接口方法增删改查提交、作废、审核、撤审、拒绝。他们的 url前面的 sales_return 拼接是固定的不同的就是后面标识功能的路径标识。另外就是method 分为 post 和 get 方法。
我们把这九个接口看成是一个 9 位二进制上的 9 个位1 代表存在0 代表不存在。
我们可以创建一个 map 文件来做构建准备如下
export const apiEnum {// 查列表2^01: {name: list,//接口名称type: post,//接口方式},// 查详情2^12: {name: get,type: get,loading: true,//是否需要loading调度、防抖},// 删列表 2^24: {name: delete,type: post,},// 保存 或者 保存且提交2^38: {name: save,type: post,loading: true,},// 提交2^416: {name: submit,type: post,loading: true,},// 审核2^532: {name: audit,type: post,},// 撤审2^664: {name: withdraw,type: post,},// 拒绝2^7128: {name: reject,type: post,},// 作废2^7256: {name: discard,type: post,},
};
export const apiFuncModule {// 全部COMMON: 511,// 增删改查CURD: 15,
}; 当我传 1 的时候九位为000000001,代表只有一个查接口。当我传 15 的时候九位为000001111,代表拥有增删改查四个接口。以此类推。
接下就是完成处理函数完成上面的功能如下 import request from /utils/request;
import { apiEnum, apiFuncModule } from /enum/baseModule/apiEnum;
function useApi(moduleName, code 511) {let apiMap {};for (let key in apiEnum) {if ((key code) key) {let obj apiEnum[key];//可以按自己习惯来对接口函数命名let apiName api_ obj.name;apiMap[apiName] (data) {return request({url: /${moduleName}/${obj.name},method: obj.type,[obj.type get ? params : data]: data,loading: obj.loading,});};}}return apiMap;
}
export { useApi, apiFuncModule as apiType }; 完成以上步骤我们的接口文件就可以这样写了,这样九个接口就写完了。而且一目了然如需修改只需要调整传参就行了。
import { useApi } from /utils/system/apiGenPlugin;
//code可以不传 默认为511
export const API useApi(sales_return);
//若有其他特殊接口 兼容原始写法 互不影响
export function xxxxx(data) {...
} 使用方式 //API集中管理
import { API as SalesReturn } from /api/workApi/sale/return;
const {api_save,api_delete,api_get,api_list,api_audit,api_withdraw,api_discard,api_submit,api_reject} SalesReturn
//单独使用
import { useApi } from /utils/system/apiGenPlugin;
const {api_save,api_delete,api_get,api_list,api_audit,api_withdraw,api_discard,api_submit,api_reject} useApi(sales_return) 增 SalesReturn.api_save删 SalesReturn.api_delete改 SalesReturn.api_get查 SalesReturn.api_list审核 SalesReturn.api_audit撤审 SalesReturn.api_withdraw作废 SalesReturn.api_discard提交 SalesReturn.api_submit拒绝 SalesReturn.api_reject
任务调度、Loading调度
实际开发中我们可能会有对接口调用做一些处理
1.对提交事件进行防抖处理防止重复提交。 2.加载某些重要资源的时候希望有个loading效果来优化用户体验。 3.让多个需要loading效果的接口共用同一个loading防止页面闪烁。
这些功能单独处理起来就显得很麻烦了而且每个人的写法不一样后期维护成本就更难。
废话不多说直接贴代码
接口调度类
import { Loading } from element-ui;
class RequestLock {// Loading 实例L_instance null;// 接口mapreqMap new Map();// 最近一次调用接口时间戳timestamp 0;
constructor(timeout 500) {// 过渡时间this.timeout timeout;}// 创建任务put (id) {if (this.reqMap.has(id)) return false;this._put(id);return true;};_put (id) {this.timestamp new Date().getTime();this.reqMap.set(id, true);//开启loadingthis.L_instance Loading.service({fullscreen: true,background: rgba(255, 255, 255, 0.1),lock: true,});};// 移除任务del (id) {if (this.reqMap.has(id)) {this.reqMap.delete(id);
if (this.reqMap.size 0) {this._closeLoading();}}};// 清空所有的任务clearTask () {this.reqMap.clear();this.L_instance.close();};//平滑关闭loading_closeLoading () {let _timestamp new Date().getTime();let settime _timestamp - this.timestamp;if (settime this.timeout) {this.L_instance?.close();} else {setTimeout(() {this.L_instance?.close();}, this.timeout - settime);}};
}
export default RequestLock;
在axios里的使用
这个是增量优化在不影响以前代码的条件下添加功能
import { RequestLock } from /class/lock;
let loadLock new RequestLock(500);
//请求拦截
service.interceptors.request.use((config) {...//如果配置中有loading 开启调度if (config.loading) {if (!loadLock.put(config.url)) {return Promise.reject(new Error(repeat request));}}...return config;},(error) {...//如果有错误请求中止当前调度任务并清空loadLock.clearTask();...return Promise.reject(error);}
);
//响应拦截
service.interceptors.response.use((response) {...//检查response.config.loading loadLock.del(response.config.url);...},(error) {loadLock.clearTask();return Promise.reject(error);}
); 接口文件书写
// 根据Id获取销售退货
export function getSalesReturn(query) {return request({url: /sales_return/get,method: get,params: query,//在这里配置loading为true开启loading:true});
} 提示信息自由化
有时候当我删除一条数据需要有个弹框提示删除是否成功。通常我们会在接口成功回调的时候加上这个功能。需要判断状态来显示提示框的描述和颜色。另一方面有时候删除一条数据业务需求提示不单单是简单的“删除成功”还可能需要其他的附加提示。比如“删除单据xxx成功请及时处理xxxx”。这种需求没什么难度但是有沟通成本和维护成本。业务有一些变化就需要修改。
另一方面后端对系统的业务逻辑更加贴近提示功能交给后端更加合理。当然前端也需要保留这个功能去兼容某些需求。
import { Message } from element-ui;
export function responseMsgHandle(res) {//这里需要后端响应数据格式的配合MsgType表示提示状态Msg表示提示描述let { MsgType, Msg } res;if ([success, warning, error].includes(MsgType)) {Message({message: Msg,type: MsgType,duration: 5 * 1000,});}
} 使用
import { responseMsgHandle } from /utils;
//响应拦截
service.interceptors.response.use((response) {...const res response.data;responseMsgHandle(res);...},(error) {...responseMsgHandle({MsgType:error,Msg:error.message,});...return Promise.reject(error);}
); 总结
以上三个简单的优化方案可以组合使用也可以单独使用。可以根据自己的实际项目需求进行改造使用。
基本上能解决很大一部分的重复劳动还能减少维护成本。
最后
最近找到一个VUE的文档它将VUE的各个知识点进行了总结整理成了《Vue 开发必须知道的36个技巧》。内容比较详实对各个知识点的讲解也十分到位。 有需要的小伙伴可以点击下方卡片领取无偿分享