- 对象转数组的树形结构,默认子元素使用children作为字段名, 可修改。
- 默认使用
$parentId $id 方便进行遍历查找 (但不推荐直接遍历,层级太深数据太多的时候会有性能问题,我配合另外加了一个 使用 $id 作为key的map来直接获取/修改值的)
- 没有添加层级level等字段,根据自己需求添加
对象转数组的树形结构 代码如下:
interface IDataSource {
$id: string
$parentId: string
children?: IDataSource[]
childrenKeyName?: string
}
export const convertToTreeData = (p: {
data: any
parentType?: string
$parentId?: string
childrenKeyName?: string
}): IAPITableItemType[] => {
const {
data,
parentType = '',
$parentId = '',
childrenKeyName = 'children',
} = p
const result = []
let index = 1
for (const key in data) {
if (data.hasOwnProperty(key)) {
let currentObject = data[key]
const t: any = typeof currentObject
let currentType = t
if (t === 'object' && Array.isArray(currentObject)) {
currentType = 'array'
currentObject = [currentObject[0]]
}
const id = uuid()
const item: any = {
$id: id,
$parentId: $parentId,
name: key,
value: t === 'object' ? '' : currentObject,
type: currentType,
parentType,
required: data?.[key]?.required,
[childrenKeyName]: undefined as any,
description: '',
}
if (typeof currentObject === 'object' && currentObject !== null) {
item[childrenKeyName] = convertToTreeData({
data: currentObject,
parentType: item.type,
$parentId: id,
childrenKeyName: childrenKeyName,
})
}
result.push(item)
index++
}
}
return result
}
当然,我也提供了 数组转回对象的方法:
export const convertToJSON = (
treeData: IAPITableItemType[],
type = 'object'
) => {
const result: any = {}
for (const item of treeData) {
const { name, value, children, type } = item
if (children && children.length > 0) {
result[name] = convertToJSON(children, type)
} else {
result[name] = value
}
}
if (type === 'array') {
return Array.from({
...(result || {}),
length: Object.keys(result),
})
} else {
return result
}
}