最近遇到个需求,简单描述下需求,就是通过一组循环嵌套数据渲染后的页面,当点击页面某一列数据时候,我可以在当前列的同级插入一条(兄弟)数据,这个就很灵活了,因为数据是无限嵌套,唯一可追寻的就是唯一id了。一时有些懵逼,后来研究下,在此记录一波,该后期还是能遇到的
tree数据源
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| let tree = [
{
id: 8,
children: [
{
id: 9,
children: []
},
{
id: 10,
children: []
}
]
},
{
id: 24,
children: [
{
id: 25,
children: [
{
id: 26,
children: []
}
]
}
]
},
{
id: 30,
children: [
{
id: 31,
children: [
{
id: 32,
children: [
{
id: 33,
children: []
}
]
}
]
}
]
}
] |
方法一
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| let off = true
function treeFn (treeData , id ) {
treeData .map ((item , ind , arr ) => {
if (item .id == id && off ) {
arr .push ({
id : 100,
children : []
})
off = false
} else if (item .children .length && off ) {
treeFn (item .children , id )
}
})
return tree
}
console .log('tree', treeFn (tree , 32)) |
方法二
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| function treeFn (arr , id , p = false) {
// 往传入的id同级新增节点
// arr.reduce(
// (total, item, index, arr) => {
// item.id == id ? (arr.push({ id: 100,children:[] })) : total ? total : treeFn(item.children, id, total)
// },
// p
// );
// return arr
//获取当前id节点数据
return arr .reduce (
(total , item , index , arr ) => { return item .id == id ? item : total ? total : treeFn (item .children , id , total ) }
,
p
);
}
console .log(treeFn (tree , 33)) |
方法三(来自Q群的召唤)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| /**
* 根据子级ID在同级中追加数据
* @param {*} tree 树型数据
* @param {*} id 查找的节点ID
* @param {*} node 添加的节点
*/
let addTree = (treeData , nodeId , nodeObj ) => {
if (!Array.isArray (treeData ) || treeData .length === 0) {
return treeData ;
}
const data = JSON .parse (JSON .stringify (treeData ));
let findParentIdAppend = (tree , id , node , parentId , pushBool ) => {
tree .map (item => {
if (item .id == id ) {
//这里再次调用是为因为需要通过父级ID再次遍历添加(通过参数pushBool来判断是查找ID还是Push)
pushBool ? (item .children && item .children .push (node )) : findParentIdAppend (data , parentId , node , parentId , true);
} else {
//这里递归是为了查找父级ID
(item .children && item .children .length > 0) && findParentIdAppend (item .children , id , node , item .id , pushBool );
}
})
return tree ;
}
return findParentIdAppend (data , nodeId , nodeObj );
}
console .log(addTree (tree , 26, {
id : 55,
name : '张三'
})); |
根据id删除数组或对象的某一项
1 2 3 4 5 6 7 8 9 10 11 12 13
| function deleteNode (id , obj ) {
if (typeof obj !== 'object' || obj === null) {
return obj
}
const arr = Array.isArray (obj ) ? [] : {};
Object .keys (obj ).forEach(key => {
if (id !== obj [key].id ) {
arr [key] = deleteNode (id , obj [key])
}
})
return arr ;
}
console .log(deleteNode (24, tree )) |
小结
只要谈到tree树状结构,那么递归是很难避免的,前面方法一核方法二主要是通过递归+在循环过程中拿到当前循环体的数组arr,通过改变当前子集的arr从而改变了原始数据tree,原理还是根据数据引用类型,两个对象指向的是同一个地址,所以改变其中一个就会改变另一个。
「梦想一旦被付诸行动,就会变得神圣,如果觉得我的文章对您有用,请帮助本站成长」
共 0 条评论关于"tree树形加载-嵌套数据格式的增删查改"
最新评论