前言
今天接了一个需求,产品想要一个扁平化数组可支持拖拽,更改标签实现树嵌套排序的功能。
要求
- 1.树结构与扁平化数组需要可以互相转化
- 2.支持扁平化数组排序、增加、删除、插入、替换
- 3.支持树结构拖拽(利用el-tree的可拖拽)
树结构转扁平化数组
function flattenAndSort(treeData) {
const flattenedData = [];
// 定义递归函数
const flattenRecursive = (node, parentId, index) => {
// 生成当前节点的id
const id = parentId ? `${parentId}-${index + 1}` : `${index + 1}`;
// 添加当前节点到扁平化数组中
flattenedData.push({ label: node.label, id });
// 递归处理子节点
if (node.children) {
node.children.forEach((child, idx) => flattenRecursive(child, id, idx));
}
};
// 遍历每个根节点
treeData.forEach((root, index) => flattenRecursive(root, null, index));
return flattenedData;
}
// 示例数据
const data = [
{
label: 'Level one 1',
children: [
{
label: 'Level two 1-1',
children: [
{
label: 'Level three 1-1-1',
},
],
},
],
},
{
label: 'Level one 2',
children: [
{
label: 'Level two 2-1',
children: [
{
label: 'Level three 2-1-1',
},
],
},
{
label: 'Level two 2-2',
children: [
{
label: 'Level three 2-2-1',
},
],
},
],
},
{
label: 'Level one 3',
children: [
{
label: 'Level two 3-1',
children: [
{
label: 'Level three 3-1-1',
},
],
},
{
label: 'Level two 3-2',
children: [
{
label: 'Level three 3-2-1',
},
],
},
],
}
];
// 调用函数扁平化数据
const flattenedData = flattenAndSort(data);
console.log(flattenedData);
扁平化数组转树结构
对扁平化数组处理
// 提取父节点
const flattenedData = [
{ label: 'Level one 1', id: '1' },
{ label: 'Level two 1-1', id: '1-1' },
{ label: 'Level three 1-1-1', id: '1-1-1' },
{ label: 'Level one 2', id: '2' },
{ label: 'Level two 2-1', id: '2-1' },
{ label: 'Level three 2-1-1', id: '2-1-1' },
{ label: 'Level two 2-2', id: '2-2' },
{ label: 'Level three 2-2-1', id: '2-2-1' },
{ label: 'Level one 3', id: '3' },
{ label: 'Level two 3-1', id: '3-1' },
{ label: 'Level three 3-1-1', id: '3-1-1' },
{ label: 'Level two 3-2', id: '3-2' },
{ label: 'Level three 3-2-1', id: '3-2-1' },
];
flattenedParent(flattenedData) {
const transformedData = [];
for (let i = 0; i < flattenedData.length; i++) {
const current = flattenedData[i];
transformedData.push({ ...current }); // Copy the current object
// Get parent id from current id
const parentId = getParentId(current.id);
if (parentId !== null) {
transformedData[i].parentId = parentId; // Add parentId to the current object in the new array
}
}
return transformedData
function getParentId(childId) {
const parts = childId.split('-');
if (parts.length === 1) {
// If there's no dash, it's a top-level node
return null;
} else {
// Remove the last part to get the parent id
parts.pop();
return parts.join('-');
}
}
}
console.log(flattenedParent(flattenedData));
扁平化数组转 树结构
// 扁平化转树
const flattenedData = [
{ label: 'Level one 1', id: '1' },
{ label: 'Level two 1-1', id: '1-1', parentId: '1' },
{ label: 'Level three 1-1-1', id: '1-1-1', parentId: '1-1' },
{ label: 'Level one 2', id: '2' },
{ label: 'Level two 2-1', id: '2-1', parentId: '2' },
{ label: 'Level three 2-1-1', id: '2-1-1', parentId: '2-1' },
{ label: 'Level two 2-2', id: '2-2', parentId: '2' },
{ label: 'Level three 2-2-1', id: '2-2-1', parentId: '2-2' },
{ label: 'Level one 3', id: '3' },
{ label: 'Level two 3-1', id: '3-1', parentId: '3' },
{ label: 'Level three 3-1-1', id: '3-1-1', parentId: '3-1' },
{ label: 'Level two 3-2', id: '3-2', parentId: '3' },
{ label: 'Level three 3-2-1', id: '3-2-1', parentId: '3-2' },
];
function unflattenTree(flattenedData) {
const tree = [];
const map = {}; // Create a map to store references to nodes by id
flattenedData.forEach(node => {
map[node.id] = { ...node, children: [] }; // Initialize each node with an empty children array
});
Object.values(map).forEach(node => {
if (node.parentId) {
// If node has a parentId, add it as a child of the parent node
map[node.parentId].children.push(node);
} else {
// Otherwise, it's a root node, add it to the tree
tree.push(node);
}
});
return tree;
}
const treeData = unflattenTree(flattenedData);
console.log(treeData);