js去除后端返回json的冗余字段
前言
在前后端交互过程中(特别是大型项目),一般要求双方传递必要的json数据。
例如后端返回给前端的json对象,不要直接把数据库实体类直接返回给前端,往往还需要转成一个VO
,因为有些宽表在库中可能有几十个字段,而前端展示&逻辑操作往往只需其中的一部分。
前端请求后端接口,如果涉及到json参数传递,需要在json中封装必要的属性,而不是直接将后端返回的json又作为参数传入。
见过一个极端的案例,在某xx管理列表展示页面,前端只需要20
个字段,但是后端返回了所有实体70+
字段,在列表进入详情页面时,界面上需要根据xx的3个属性请求关联的业务接口获取最新的详情信息,前端没有构建查询json,而是省事直接将先前包含70+
字段的json直接作为参数传入。这样一来会浪费80%
以上的带宽资源,本文关注如果后端确实直接返回了数据库实体,存在较多冗余字段,并且这个接口后续也不会调整了,前端在给页面赋值时有什么补救措施(页面大批量渲染时减少不必要的属性判断)?
确认需要去除的冗余字段
例如后端返回了一个对象数组,其中每一个对象的extAttribute11~extAttribute20是
多余的,需要在获取响应后处理掉再对页面进行赋值渲染
去除冗余字段
大体上有两种思路来实现去除冗余字段的效果:
一、去除指定字段
二、保留指定字段
封装去除指定字段方法
方法定义
ts
代码
// methodUtil.ts
/**
* 去除对象数组中的冗余字段,只保留指定字段
* @param data 对象数组
* @param fieldsToRemove 需要保留的字段数组
* @returns 去除冗余字段后的对象数组
*/
export function removeRedundantFields<T extends Record<string, any>>(
data: T[],
fieldsToRemove: (keyof T)[]
): Partial<T>[] {
return data.map((item) => {
const newItem = { ...item };
fieldsToRemove.forEach((field) => {
delete newItem[field]
});
return newItem;
});
}
js
代码
// methodUtilJs.js
/**
* 去除对象数组中的冗余字段,只保留指定字段
* @param data 对象数组
* @param fieldsToRemove 需要保留的字段数组
* @returns 去除冗余字段后的对象数组
*/
export function removeRedundantFields (data, fieldsToRemove) {
return data.map((item) => {
const newItem = { ...item }
fieldsToRemove.forEach((field) => {
delete newItem[field]
})
return newItem
})
}
封装保留指定字段方法
方法定义
ts
代码
// methodUtil.ts
/**
* 保留对象数组指定字段
* @param data 对象数组
* @param fieldsToKeep 需要保留的字段数组
* @returns 去除冗余字段后的对象数组
*/
export function keepFields<T extends Record<string, any>>(
data: T[],
fieldsToKeep: (keyof T)[]
): Partial<T>[] {
return data.map((item) => {
const newItem: Partial<T> = {};
fieldsToKeep.forEach((field) => {
if (item.hasOwnProperty(field)) {
newItem[field] = item[field];
}
});
return newItem;
});
}
js
代码
// methodUtilJs.js
/**
* 保留对象数组指定字段
* @param data 对象数组
* @param fieldsToKeep 需要保留的字段数组
* @returns 去除冗余字段后的对象数组
*/
export function keepFields (data, fieldsToKeep) {
return data.map((item) => {
const newItem = {}
fieldsToKeep.forEach((field) => {
if (Object.prototype.hasOwnProperty.call(item, field)) {
newItem[field] = item[field]
}
})
return newItem
})
}
测试验证
可根据实际情况使用上述封装的ts
或js
代码
const bizId = '0777c40218114c35a29b0d4d84355668'
await axios.post(`/asset/assetInfo/${bizId}/byBizId`).then(result => {
if (result.status === 200) {
const assetInfoList = result?.data?.data?.assetInfoList
console.log('assetInfoList', assetInfoList)
const removeResult = removeRedundantFields(assetInfoList, ['extAttribute11', 'extAttribute12',
'extAttribute13', 'extAttribute14', 'extAttribute15', 'extAttribute16', 'extAttribute17', 'extAttribute18',
'extAttribute19', 'extAttribute20'])
console.log('removeResult', removeResult)
const keepResult = keepFields(assetInfoList, ['assetNumber', 'assetStatus', 'useDeptCode', 'createTime',
'createByUuid', 'createByAccount', 'createByName', 'lastUpdateTime', 'lastUpdateUuid', 'lastUpdateAccount',
'lastUpdateName', 'extAttribute1', 'extAttribute2', 'extAttribute3', 'extAttribute4', 'extAttribute5',
'extAttribute6', 'extAttribute7', 'extAttribute8', 'extAttribute9', 'extAttribute10', 'bizId'
])
console.log('keepResult', keepResult)
}
})
去除指定字段
保留指定字段
成功去除了每一个对象的extAttribute11~extAttribute20
属性