场景
目前需要实现多个tab
页面切换,并且tab
页存在很多的默认值需要前端进行设置
想法和引入
因为存在大量的默认值
需要进行判断,如果采用大量的if-else
,那么可能会导致代码比较零散,以后维护起来非常的困难。
所以就可以想到,策略模式,专门用于优化if-else
过多的问题
简单来概括一下他的用法:枚举类+Map:抽象为对象/Map,然后 Map 对象直接匹配
具体抽象为map
还是object
,可以根据具体情况来进行判断
- 枚举出所有需要默认的值
- 将他们都放在一个
Map
里面 - 后续需要用用到哪一个,只要
get/set
就可以了
代码和使用
typescript
/**
* @description 获取表单的默认值
* @param param0
* @returns
*/
export function getDefaultValues({
materialType,
materialTypeDesc,
}: GetListValueProps) {
// 可复用性检查数据
const availabilityCheckDataMap = {
ZA10: "KP 无检查",
ZE50: "KP 无检查",
ZF60: "KP 无检查",
ZB20: "02",
ZC30: "02",
ZD40: "02",
ZG70: "02",
ZJ80: "02",
ZH90: "02",
};
// 项目类别组数据
const itemCategoryGroupDataMap = {
ZB20: "NORM",
ZC30: "NORM",
ZD40: "NORM",
ZG70: "NORM",
ZH90: "NORM",
ZA10: "ERLA",
ZF60: "DIEN",
};
// MRP类型数据
const mrpTypeDataMap = {
ZB20: "PD",
ZC30: "PD",
ZD40: "PD",
};
// 计划参数文件
const planningParameterFileDataMap = {
ZB20: "000001",
ZC30: materialTypeDesc === "半成品" ? "000001" : "",
};
// 价格确定
const priceDeterminationDataMap = {
ZC30: materialTypeDesc === "BOM原料" ? "2" : materialTypeDesc === "非BOM原料" ? "2" : "",
ZC50: materialTypeDesc === "非生产物资" ? "2" : ""
};
return {
// 销售视图默认值
availabilityCheck: availabilityCheckDataMap[materialType],
itemCategoryGroup: itemCategoryGroupDataMap[materialType],
// 生产视图默认值
mrpType: mrpTypeDataMap[materialType] || "ND", // 默认值为'ND'
planParamFile: planningParameterFileDataMap[materialType], // 默认值为undefined
priceDetermination: priceDeterminationDataMap[materialType]
};
}
- 我将获取默认值这个事情封装为一个函数,专门用于获取默认值
- 将所有的枚举都按照
key-value
的格式列出来 - 最后将他们返回
typescript
const defaultValues = getDefaultValues({
materialType: baseView?.materialType,
materialTypeDesc: baseView?.materialTypeDesc,
}); // 获取所有的默认值
setDefaultData({
...initSetting.viewData,
saleView: {
...saleView,
availabilityCheck:
saleView?.availabilityCheck || defaultValues.availabilityCheck,
itemCategoryGroup:
saleView?.itemCategoryGroup || defaultValues.itemCategoryGroup,
},
mrpView: {
...mrpView,
mrpType: mrpView?.mrpType || defaultValues.mrpType,
usingCheck: mrpView?.usingCheck || defaultValues.availabilityCheck,
},
financeView: {
...financeView,
priceDetermination:
financeView?.priceDetermination || defaultValues.priceDetermination,
},
});
其实个人感觉,我上面这个代码更像是将代码直接抽离出来,封装为函数,和策略模式有些联系,但不是很大。
或者我们tab
页面切换视图的时候,每一个 tab
页面都会携带各自的onFinish
方法和他们的页面,我们就可以将他们都放到一个onject
里面,后续使用只要直接去调用就好
typescript
// 设置维护Items的对应关系
const maintenanceItemsMap = {
baseView: {
label: "基础视图",
children: BasicView(),
key: "baseView"
},
saleView: {
label: viewLossStatus.lossSaleView ? "销售视图(缺失)" : "销售视图",
children: SalesMaintenance(),
onFinish: saleFormSubmit,
key: "saleMaintenanceView"
},
purchaseView: {
label: viewLossStatus.lossPurchaseView ? "采购视图(缺失)" : "采购视图",
children: PurchaseMaintenance(),
onFinish: purchaseFormSubmit,
key: "purchaseMaintenanceView"
},
mrpView: {
label: viewLossStatus.lossMrpView ? "生产视图(缺失)" : "生产视图",
children: ProductionMaintenance(),
onFinish: mrpFormSubmit,
key: "mrpMaintenanceView"
},
financeView: {
label: viewLossStatus.lossFinanceView ? "财务视图(缺失)" : "财务视图",
children: FinanceMaintenance(),
onFinish: financeFormSubmit,
key: "financeMaintenanceView"
},
};
// 根据返回的参数,isView和checkedKeys,来显示对应的视图
function getViewItems() {
const { isView, checkedKeys } = initSetting;
return checkedKeys.map((key: string) => {
return {
key,
label: maintenanceItemsMap[key].label,
children: maintenanceItemsMap[key].children,
};
});
}
参考链接
一文搞懂策略模式(优化策略模式完全消除if else)_策略模式优化-CSDN博客(易于理解)
前端设计模式之策略模式 - 掘金(评论区)