优秀代码汇总学习(一)
需求详情
对后端接口返回的数据做兜底处理:
为保证项目的健壮性,前端项目应对用户输入数据和接口返回数据做检验兜底处理。
为了防止后端返回乱码导致前端页面显示不友好的问题,对后端数据做了兜底处理:有 key 的属性就调用getByKey 函数先获取,将 对应的 title 属性值作为默认值
实现
数据类型定义
接口返回的 data 是 Category[] | null 类型的
以下是 ts 定义文件:
export interface Category {
categoryId?: number | null;
/**
* 类目
*/
categoryName?: string | null;
/**
* 类目 key
*/
categoryNameKey?: string | null;
/**
* 旗下课程
*/
courses?: Course[] | null;
}
export interface Course {
/**
* 课程标签
*/
tag?: CourseTag[] | null;
/**
* 课程指南标题
*/
title?: string | null;
/**
* 课程标题 key
*/
titleKey?: string | null;
url?: string | null;
regionType?: number[] | null;
}
export interface CourseTag {
tagName?: string | null;
tagKey?: string | null;
}
具体实现
旧设计实现
-
为了遵循可维护性,采用了 map 来保存 title 与 titleKey,该 data 存在三种 title 与 key 的对应
const map = { titleKey: 'title', categoryNameKey: 'categoryName', tagKey: 'tagName' };
-
遍历data,若 getByKey(titleKey) 没有返回对应的文字,则采用 title 返回的值,避免后端返回的 key 乱码,前端展示不友好的情况
缺点
- 只要后端修改了契约(ts文件变化),前端就需要手动维护 map,保证一致性,操作比较麻烦,并且可维护性不强
- 代码不够优雅
新设计实现
充分利用 ts ,如下实现:
const formatData = (data: Category[]) => {
return data.map((item) => {
const { categoryName, categoryNameKey, courses } = item;
return {
...item,
categoryName: getDefaultValue(categoryName, categoryNameKey),
courses: courses?.map((cItem) => {
const { title, titleKey, tag } = cItem;
return {
...cItem,
title: getDefaultValue(title, titleKey),
tag: tag?.map((tItem) => {
const { tagName, tagKey } = tItem;
return {
...tItem,
tagName: getDefaultValue(tagName, tagKey)
};
})
};
})
};
});
};
function getDefaultValue(name?: string, key?: string) {
return getByKey({ key: key }) || name;
}
优点
- 代码比较优雅
- 充分利用 ts
小菜鸟前端进击,一天天进步!
有错欢迎大家指正