【功能实现】开关控制相似结构中不同内容的展示

506 阅读4分钟

一、前言

最近在做开发设计的时候,对于已有功能添加新功能的需求,进行了沉思,以往在已有需求上进行功能叠加,会对部分条件判断进行新增或者整合,那么就会有一个问题,整合操作会影响现有功能。大部分情况下,在提测的时候我会特别说明影响范围,个别情况提测时会漏掉。这样一来既不利于线上代码的正确性,又方便代码的扩展和维护。

所以,在新需求开发设计阶段,我跳出了原有的思维定式,设计了下面的功能。

分享代码基于recat框架。

二、功能分析

2.1 UI

image.png

2.2 功能解析

现有功能中,鞋子看板和帽子看板的展示类型完全一致,仅不同类型下的具体数据不同。

新需求,将鞋子看板中原有的今日已付款和本月已付款改为了上月已付款和上年已付款。

三、开发设计

3.1 以往思路

在以往的开发思路中,自然而然的列表展示之前进行列表重组,根据看板类型的不同,区分不同内容。

if (type === 'shoses' && (item.key === '上月已付款' || item.key === '上年已付款') ) { 
    // 鞋子看板加入两项 
} 
if (type === 'hat' && (item.key === '今日已付款' || item.key === '本月已付款') ) 
{ 
    // 帽子看板加入两项 
}

如果后续新增其他类型看板或者鞋子看板新增其他项展示或者帽子看板增其他项展示,条件语句需要继续新增,不方便维护,并且容易影响已有功能。

3.2 思维转换

对于内容展示,只有展示和不展示两种情况中的一种,类似灯亮与不亮,是通过电源开关控制,这里也可以控制不同看板下的类型展示开关,即不影响原有功能,又方便后续扩展。

四、具体实现

4.1 设置看板变量

/** @name 看板类别对象  */
const boardObj = {
    1 : {
        key: 'shoes',
        // 唯一key
        name: '鞋子',
        // 看板展示标题
        class: 1,
        // 和后端数据对应的值
    },
    2 : {
        key: 'hat',
        name: '帽子',
        class: 2,
    },
};

4.2 设置看板展示具体项的对象

包含展示涉及的全部项,需要区分看板类型的项,设置控制开关的值。

/** @name 看板展示具体项的对象  */
const boardOption = {
	name: '看板',
	list: [{
		key: 'allPay',
		// 唯一key
		name: '全部待付款',
		// 展示名称
		selfStyle: {
			color: '#d9041b',
		},
		// 字体颜色
		sumNum: '',
		// 展示值
		sumKey: 'allPay',
		// 展示值的key
	},
	{
		key: 'today',
		name: '今日已付款',
		selfStyle: {
			color: '#2eaaaa',
		},
		sumNum: '',
		sumKey: 'today',
		moduleShowType: 'hat',
		// 模块展示控制开关
	},
	{
		key: 'month',
		name: '本月已付款',
		selfStyle: {
			color: '#2eaaaa',
		},
		sumNum: '',
		sumKey: 'month',
		moduleShowType: 'hat',
	},
	{
		key: 'lastMonth',
		name: '上月已付款',
		search: '',
		selfStyle: {
			color: '#F59A23',
		},
		sumNum: '',
		sumKey: 'lastMonth',
		moduleShowType: 'shoes',
	},
	{
		key: 'lastYear',
		name: '上年已付款',
		search: '',
		selfStyle: {
			color: '#F59A23',
		},
		sumNum: '',
		sumKey: 'lastYear',
		moduleShowType: 'shoes',
	},
	{
		key: 'year',
		name: '今年已付款',
		selfStyle: {
			color: '#2eaaaa',
		},
		sumNum: '',
		sumKey: 'year',
	},
	],
};

4.3 数据初始化

将页面请求数据进行初始化,转换成我们需要的能展示到页面的数据。

/** @name 页面展示看板列表数组  */
const[boardList, setBoardList] = useState([]);

useEffect(() =>{
	let dataList = [{
		allPay: 1100,
		class: 1,
		month: 10,
		lastMonth: 10,
		lastYear: 100,
		today: 2,
		year: 200,
	},
	{
		allPay: 2200,
		class: 2,
		month: 20,
		lastMonth: 30,
		lastYear: 400,
		today: 2,
		year: 299,
	},
	];
	const list = [];
	dataList.forEach(item =>{
		let boardItem = boardObj[item.class];
		boardItem.board = _.cloneDeep(boardOption);
		boardItem.board.list.forEach(board =>{
			board.sumNum = item[board.sumKey];
		});
		list.push(boardItem);
	});
	setBoardList(list);
},
[]);

最终得到数据结构如下图,其中shoes和hat两个分类的结构是基本一致的。

image.png

4.4 看板项开关设置方法

开关的具体逻辑如下:

1)不设置开关字段的项直接展示;

2)设置开关字段的项,根据内容里面的具体看板类型进行展示

/**
   * 看板项开关设置方法
   * @param {Object} board 看板项数据
   * @param {Object} item 看板数据
   * @return {boolean} 看板项展示布尔值
   */
const moduleShowFlag = (board, item) =>{
	let flag = false;
	// =>true: 不设置开关字段的项直接展示
	if (!board.moduleShowType) {
		flag = true;
	} else {
		// =>true: 设置开关字段的项,根据内容里面的具体看板类型进行展示
		if (board.moduleShowType.includes(item.key)) {
			flag = true;
		}
	}
	return flag;
};

4.5 页面渲染

初始化好的列表数据循环渲染,不同看板类型展示具体项添加开关设置方法,根据返回的布尔值进行展示。 注:代码复制不全,所以直接贴了图片

image.png

五、结束

一次简单的改变,可能会使前方的路豁然开朗。

本次分享结束,新人刚开始尝试写文,欢迎大家评论区畅言,给出宝贵意见,帮助我不断成长。