如何用JavaScript将动态JSON转为el-table所需的树形结构?
问题描述
需要将MongoDB返回的动态对象数组数据,转换为适合前端tree-table展示的树形结构:
原始JSON数据:
const Collection = { Fields: [{ fieldName: 'mainField', properties: [{ id: 1, carName: 'carName_01', type: 'string' // 修正原数据的引号缺失问题 }, { id: 2, carName: 'carName_02', type: 'object', ref: 'subField' }] }, { fieldName: 'subField', properties: [{ id: 1, carName: 'carName_11', type: 'string' }, { id: 2, // 修正原数据的id重复问题,实际业务需保证id唯一 carName: 'carName_12', type: 'object', ref: 'subField1' }] }, { fieldName: 'subField1', properties: [{ id: 1, carName: 'carName_21', type: 'string' }] }] };
目标树形结构:
const tableData = [{ id: 1, carName: 'carName_01', type: 'string' }, { id: 2, carName: 'carName_02', type: 'object', source: 'subField', children: [{ id: 1, carName: 'carName_11', type: 'string' }, { id: 2, carName: 'carName_12', type: 'object', source: 'subField1', children: [{ id: 1, carName: 'carName_21', type: 'string' }] }] } ];
核心要求:当节点type: 'object'且存在ref字段时,自动添加children字段,将ref指向的字段的properties作为子节点。
解决方案
1. 构建字段映射表
先将Fields转换为以fieldName为键的映射对象,避免递归时反复遍历数组,提升查询效率:
const fieldMap = Collection.Fields.reduce((map, field) => { map[field.fieldName] = field.properties; return map; }, {});
2. 编写递归转换函数
遍历每个属性节点,判断是否需要生成子节点:
function convertToTree(properties) { return properties.map(item => { // 复制当前节点基础属性 const node = { ...item }; // 按目标结构将ref替换为source if (node.ref) { node.source = node.ref; delete node.ref; } // 若为object类型且存在有效source,递归生成children if (node.type === 'object' && node.source && fieldMap[node.source]) { node.children = convertToTree(fieldMap[node.source]); } return node; }); }
3. 执行转换(从mainField开始)
const tableData = convertToTree(fieldMap.mainField); console.log(tableData);
关键说明
- 映射表
fieldMap:快速通过source(原ref)获取对应字段的properties,避免循环遍历的性能损耗。 - 递归逻辑:对每个节点复制基础属性后,判断是否满足生成子节点的条件,满足则递归处理子字段的属性。
- 数据校验:原数据存在格式错误(引号缺失、id重复),实际使用时需保证原始数据格式合法,否则会导致转换失败。
内容的提问来源于stack exchange,提问作者Shadow-Monarach
相关产品推荐
相关产品推荐

