功能描述
根据后端返回的一个Id,展示对应的name,hover时展示完整层级的name
心路历程
因为是级联数据,层级较多,一层层来回遍历取值消耗性能又麻烦。本着后端处理方便后端弄,前端处理方便前端弄的想法,想让后端加个字段处理好直接返回,前端直接展示(也想着偷懒😹),奈何后端大佬及前端大佬已说好了前端处理🤷♀️。
着手处理时,发现级联数据结构也够简单,children里的数据只有name,id字段,parentId也没。让后端同学加上parentId,前端方便处理时,emm。。。,等了半天数据没变。好吧,自己动手,丰衣足食!
- 返回的级联数据结构:
list:[
{
name: 'name1',
id: 'id1',
children: [
{
name: 'name2',
id: 'id2',
children: [
{
name: 'name3',
id: 'id3',
},
...
]
},
...
]
},
...
]
例:根据需求是给一个id3,展示name3,hover name3时浮动展示「name1-name2-name3」。
数据处理
前半部分比较简单,这里不做说明,只处理完整层级的问题。
第一步:首先遍历数据,使用递归的方式,给每层的数据加上parentId,代码如下:
function regroupData(dataList) {
let newList = [];
function regroupList(list, parentId) {
newList = list.map(item => {
const {
children,
id
} = item;
if (children && children.length) {
return {...item,
parentId,
children: regroupList(children, id),
};
}
return {...item,
parentId,
};
});
return newList;
}
regroupList(dataList);
return newList;
}
第二步:可以很方便的取值了
function queryDataName(list, id) {
list.forEach(item => {
const {
children
} = item;
if (item.id === id) {
names.unshift(item.name);
// 取其父级的name
queryDataName(dataList, item.parentId);
} else if (children && children.length) {
queryDataName(children, id);
}
});
return names;
}
queryDataName(dataList, id);
return names.join('-');
};
其他方法
解决问题的方式方法多种多样
在我之前,坐在我左手边的大佬同事已做过相同的功能,也看过他的代码。嗯,和我这种方法完全不同。 他的方式是把数据通过遍历改换成一种{id: name}的数据结构。
function queryName(dataList) {...
let nameMap = {};
// 这里只把重构数据结构的代码展示出来
function loopData(list, parent) {
return list.map(item => {
const {
id,
name,
children
} = item;
const node = (nameMap[id] = {
parent,
id,
name,
});
node.children = loopData(children, node);
return node;
})
};
loopData(dataList);
...
}