一、场景
在前端日常开发中,经常会根据返回的状态码判断进行相应的数据操作。在then中充斥着大量的if,这使代码非常耦合并且不直观(如图1.1),在以后维护中也是非常让人头疼。所以今天来优化一下代码
图1.1 对请求返回的数据判断然后进行相应数据操作
根据图1.1可以发现里面有多个if/else判断。可能大家会觉得图1.1里面的if/else数量还行,不需要优化,但是如果在后期中再加入多个if判断的话,then中整体的if/else会比较多。如果是自己开发的项目可以随意些,但是如果是多人开发的项目,在日后其他人维护起来因为有多个if/else判断,维护成本会提高,代码也变得不易读懂。例如图1.2
图1.2 then中大量的if/else判断
二、优化
所以我们需要优化代码,把没必要的if去掉。把代码变得可维护。这里使用模式设计中的职责链模式进行优化
- 首先 声明接口,定义两个方法
接口名称定为RequestHandle,里面有需要类进行实现的setNext和handle方法。其中setNext方法用于把各各处理类实例串成一个链条,handle方法用来处理请求
interface RequestHandle{setNext(handle:RequestHandle):RequestHandle;handle(request:any,vueThis:Vue,arg:any):boolean;
}
2.抽象类实现定义的接口,为子类继承提供方法
注意:抽象类中没有使用abstract来修饰方法,也就是说不需要子类实现,直接可以继承
abstract class AbstractRequestHandle implements RequestHandle{private nextHandler:RequestHandle;setNext(handle:RequestHandle):RequestHandle{this.nextHandler=handle;return handle;}handle(request:any,vueThis:Vue,...arg:any):boolean{if(this.nextHandler){return this.nextHandler.handle(request,vueThis,arg);}return false;}
}
3.子类继承抽象类
class RequestHandle200 extends AbstractRequestHandle{handle(requset:any,vueThis:Vue,...arg:any){if(requset === 200){vueThis.$message.success('操作成功!');vueThis.$set(vueThis, 'newGroupVis', false);vueThis.$set(vueThis, 'groupName', '');getGroupList({token: arg[0].token,keyword: '',pageNo: arg[0].currentPage,pageSize: arg[0].pageSize}).then((res:any) => {if(res.code===200){vueThis.$set(vueThis,'spinningTable',false);vueThis.$store.dispatch('groupModule/editContent',res.data)}}).catch(() => {vueThis.$set(vueThis,'spinningTable',false);})return true; }return super.handle(requset,vueThis,arg); }
}class RequestHandle409 extends AbstractRequestHandle{handle(requset:any,vueThis:Vue,...arg:any){if(requset === 409){vueThis.$message.error('分组已存在!');vueThis.$set(vueThis,'spinningTable',false);return true; }return super.handle(requset,vueThis,arg); }
}class RequestHandleOther extends AbstractRequestHandle{handle(requset:any,vueThis:Vue,...arg:any){if(requset !== 200){vueThis.$message.error('操作失败!');vueThis.$set(vueThis,'spinningTable',false);return true; }return super.handle(requset,vueThis,arg); }
}
- 实例化,形成链条,并导出
注意:形成链条的先后顺序,它会影响处理的先后顺序
const request200 =new RequestHandle200();
const requestOther = new RequestHandleOther();
const request409 = new RequestHandle409();request200.setNext(request409).setNext(requestOther);export default request200;
- vue页面使用
import request200 from './fun/cor'
和图1.1对象发现,现在的then中只有一行代码,并且不同的状态有不同类进行处理,降低了耦合和提高代码可维护性。效果如下图
三、整体代码
import Vue from 'vue'
import { getGroupList } from '../../../../api/groupList';
interface RequestHandle{setNext(handle:RequestHandle):RequestHandle;handle(request:any,vueThis:Vue,arg:any):boolean;
}
abstract class AbstractRequestHandle implements RequestHandle{private nextHandler:RequestHandle;setNext(handle:RequestHandle):RequestHandle{this.nextHandler=handle;return handle;}handle(request:any,vueThis:Vue,...arg:any):boolean{if(this.nextHandler){return this.nextHandler.handle(request,vueThis,arg);}return false;}
}class RequestHandle200 extends AbstractRequestHandle{handle(requset:any,vueThis:Vue,...arg:any){if(requset === 200){vueThis.$message.success('操作成功!');vueThis.$set(vueThis, 'newGroupVis', false);vueThis.$set(vueThis, 'groupName', '');getGroupList({token: arg[0].token,keyword: '',pageNo: arg[0].currentPage,pageSize: arg[0].pageSize}).then((res:any) => {if(res.code===200){vueThis.$set(vueThis,'spinningTable',false);vueThis.$store.dispatch('groupModule/editContent',res.data)}}).catch(() => {vueThis.$set(vueThis,'spinningTable',false);})return true; }return super.handle(requset,vueThis,arg); }
}class RequestHandle409 extends AbstractRequestHandle{handle(requset:any,vueThis:Vue,...arg:any){if(requset === 409){vueThis.$message.error('分组已存在!');vueThis.$set(vueThis,'spinningTable',false);return true; }return super.handle(requset,vueThis,arg); }
}class RequestHandleOther extends AbstractRequestHandle{handle(requset:any,vueThis:Vue,...arg:any){if(requset !== 200){vueThis.$message.error('操作失败!');vueThis.$set(vueThis,'spinningTable',false);return true; }return super.handle(requset,vueThis,arg); }
}const request200 =new RequestHandle200();
const requestOther = new RequestHandleOther();
const request409 = new RequestHandle409();request200.setNext(request409).setNext(requestOther);export default request200;
注:你也可以把接口和抽象类独立成一个文件(A文件),继承抽象类的子类独立成另一个文件(B文件),这里把A文件放在全局,以后在开发中那个页面需要用到就可以继承抽象类,生成处理单独页面的函数