前言
kk-utils 是一款我自己基于这几年开发封装出来的前端工具库
tree
tree
是kk-utils
里的工具之一(1.1.0版本开始支持)
,其作用是有多个针对树结构的方法函数,是我在写项目时积累下来的,几乎可以覆盖日常所需
当然,初始的代码是借鉴GitHub
上newarea0大佬的代码,基于此源码的基础上进行修改和新增适合我业务的功能
使用方法
安装
js
npm install kk-utils-library -S
pnpm add kk-utils-library -S
基础配置项
绝大部分函数的基础配置项都有以下选项可用
strategy
设置搜索策略,默认策略为pre
pre
:深度优先,正序搜索
post
:深度优先,反序搜索
breadth
:广度优先
js
import { filter } from 'kk-utils-library/tree';
const result = filter(tree, node => node.id > 2, { strategy: 'post' })
childrenKey
自定义子节点key
名,默认值为children
js
import { filter } from 'kk-utils-library/tree';
const result = filter(tree, node => node.id > 2, { childrenKey: 'items' })
getChildrenKey
设置一棵树上多种自定义子节点key
名
js
const getChildrenKeyTree = [
{
key: '1',
children: [
{
key: '2',
subItems: [
{
key: '3'
}
]
}
]
},
{
key: '4'
}
];
const getChildrenKeyResult = filter(
getChildrenKeyTree,
(node) => node.id > 2,
{
getChildrenKey: (tree, meta) => {
if (meta.depth === 1) {
return 'subItems';
}
}
}
);
可用方法
forEach
遍历树形数组/对象,对每个节点执行回调
js
forEach(tree, callback, [options])
tree
:树形数组/对象callback
:回调函数,对每个节点执行回调options
:配置项,可选,对象类型,支持基础配置项
js
import { forEach } from 'kk-utils-library/tree';
const data = [
{
key: 1,
children: [
{
key: 11,
children: [
{
key: 111
},
{
key: 112
}
]
},
{
key: 12,
children: [
{
key: 122,
children: [
{
key: 1221
},
{
key: 1222
}
]
}
]
}
]
}
];
forEach(data, (node) => {
console.log(node.key);
});
// 1
// 11
// 111
// 112
// 12
// 122
// 1221
// 1222
filter
遍历树形数组/对象,并把返回非真值的节点剔除(不会影响原结构,返回的树是新生成的)
js
filter(tree, callback, [options])
tree
:树形数组/对象callback
:回调函数,对每个节点执行回调options
:配置项,可选,对象类型,支持基础配置项
js
import { filter } from 'kk-utils-library/tree';
const data = [
{
key: 1,
children: [
{
key: 11,
children: [
{
key: 99
},
{
key: 112
}
]
},
{
key: 12,
children: [
{
key: 122,
children: [
{
key: 1221
},
{
key: 1222
}
]
}
]
}
]
}
];
const result = filter(data, (node) => node.key < 100);
console.log('result', result);
// {
// "key": 1,
// "children": [
// {
// "key": 11,
// "children": [
// {
// "key": 99
// }
// ]
// },
// {
// "key": 12,
// "children": []
// }
// ]
// }
conditionsFilter
遍历树形数组/对象,并把返回非真值的节点剔除
这个方法和上面的filter
的区别在于:
conditionsFilter
不支持基础配置项conditionsFilter
在父级为true
,而子级没数据的时候,可以选择携带出下一级的数据或者所有下级数据,这在比如区域列表过滤的时候,可以通过搜索省级带出所有市级或者所有子区域conditionsFilter
在能搜索匹配到最后一级的时候,并不会携带出兄弟节点conditionsFilter
支持函数过滤和对象/数组结构的值匹配过滤,但是值匹配过滤并不是全等,而是包含关系
js
conditionsFilter(tree, conditions, [options])
tree
:树形数组conditions
:过滤条件,- 可以为函数
(item) => boolean
- 也可以为对象
{ name: '名称搜索', code: '编码搜索' }
,多个条件是&&
的关系,必须都满足
- 可以为函数
options
:配置项,可选,对象类型,不支持基础配置项childrenKey
:自定义子节点key
名,默认值为children
withChildren
:子级没数据的时候是否携带子级数据返回,默认值为true
allChildren
:是否返回所有子级数据,默认值为false
js
import { conditionsFilter } from 'kk-utils-library/tree';
const data = [
{
key: 1,
children: [
{
key: 11,
children: [
{
key: 99
},
{
key: 112
}
]
},
{
key: 12,
children: [
{
key: 122,
children: [
{
key: 1221
},
{
key: 1222
}
]
}
]
}
]
}
];
const result = conditionsFilter(data, (node) => node.key === 122);
console.log('result', result);
// [
// {
// key: 1,
// children: [
// {
// key: 12,
// children: [
// {
// key: 122,
// children: [
// {
// key: 1221
// },
// {
// key: 1222
// }
// ]
// }
// ]
// }
// ]
// }
// ];
map
遍历树形数组/对象,根据返回的对象,组成新的树
js
map(tree, callback, [options])
tree
:树形数组/对象callback
:每次迭代调用的函数,需要返回一个对象,返回的对象上无需包括子节点options
:配置项,可选,对象类型,支持基础配置项
js
import { map } from 'kk-utils-library/tree';
const data = [
{
key: 1,
children: [
{
key: 11,
children: [
{
key: 111
},
{
key: 112
}
]
},
{
key: 12,
children: [
{
key: 122,
children: [
{
key: 1221
},
{
key: 1222
}
]
}
]
}
]
}
];
const result = map(data, (node) => ({ name: `No.${node.key}` }));
console.log('result', result);
// {
// "name": "No.1",
// "children": [
// {
// "name": "No.11",
// "children": [
// { "name": "No.111" },
// { "name": "No.112" }
// ]
// },
// {
// "name": "No.12",
// "children": [
// {
// "name": "No.122",
// "children": [
// { "name": "No.1221" },
// { "name": "No.1222" }
// ]
// }
// ]
// }
// ]
// }
find
遍历树形数组/对象,找到第一个返回非空值的节点
js
find(tree, callback, [options])
tree
:树形数组/对象callback
:每次迭代调用的函数,需要返回一个对象,返回的对象上无需包括子节点options
:配置项,可选,对象类型,支持基础配置项
js
import { find } from 'kk-utils-library/tree';
const data = [
{
key: 1,
children: [
{
key: 11,
children: [
{
key: 111
},
{
key: 112
}
]
},
{
key: 12,
children: [
{
key: 122,
children: [
{
key: 1221
},
{
key: 1222
}
]
}
]
}
]
}
];
const result = find(data, (node) => node.key < 100 && node.key > 10);
console.log('result', result);
// {
// "key": 11,
// "children": [
// {
// "key": 111
// },
// {
// "key": 112
// }
// ]
// }
some
遍历树形数组/对象,判断是否存在符合条件的节点
js
some(tree, callback, [options])
tree
:树形数组/对象callback
:每次迭代调用的函数,需要返回一个对象,返回的对象上无需包括子节点options
:配置项,可选,对象类型,支持基础配置项
js
import { some } from 'kk-utils-library/tree';
const data = [
{
key: 1,
children: [
{
key: 11,
children: [
{
key: 111
},
{
key: 112
}
]
},
{
key: 12,
children: [
{
key: 122,
children: [
{
key: 1221
},
{
key: 1222
}
]
}
]
}
]
}
];
const result = some(data, (node) => node.key < 100 && node.key > 10);
console.log('result', result);
// true
toArray
将树形数组/对象转换为一维数组,数组会包含所有节点
js
toArray(tree, [options])
tree
:树形数组/对象options
:配置项,可选,对象类型,支持基础配置项leafKey
:叶子节点的key
,默认为isLeaf
withChildren
:是否携带子级数据,默认为false
js
import { toArray } from 'kk-utils-library/tree';
const data = [
{
key: '1',
children: [
{
key: '2',
children: [
{
key: '3'
}
]
}
]
}
];
const result = toArray(data);
console.log('result', result);
// [
// {
// key: '1',
// isLeaf: false
// },
// {
// key: '2',
// isLeaf: false
// },
// {
// key: '3',
// isLeaf: true
// }
// ];
fromArray
将数组转换为树形数组/对象
js
fromArray(array, [options])
array
:数组options
:配置项,可选,对象类型,不支持基础配置项itemKey
:指定节点key
名,默认值为id
childrenKey
:自定义子节点key
名,默认值为children
parentKey
:自定义父节点key
名,默认值为parentId
js
import { fromArray } from 'kk-utils-library/tree';
const data = [
{
id: '1',
name: '1'
},
{
id: '2',
name: '2',
parentId: '1'
},
{
id: '3',
name: '3',
parentId: '1'
},
{
id: '4',
name: '4',
parentId: '2'
},
{
id: '5',
name: '5'
}
];
const result = fromArray(data);
console.log('result', result);
// [
// {
// id: '1',
// name: '1',
// children: [
// {
// id: '2',
// name: '2',
// parentId: '1',
// children: [
// {
// id: '4',
// name: '4',
// parentId: '2'
// }
// ]
// },
// {
// id: '3',
// name: '3',
// parentId: '1'
// }
// ]
// },
// {
// id: '5',
// name: '5'
// }
// ];
toTree
将数组转换为树形数组
这个方法和上面的fromArray
的区别在于:
toTree
支持root
顶层标识配置toTree
支持levelKey
节点层级key
配置toTree
支持leafKey
叶子节点key
配置
js
toTree(tree, conditions, [options])
tree
:树形数组conditions
:过滤条件,- 可以为函数
(item) => boolean
- 也可以为对象
{ name: '名称搜索', code: '编码搜索' }
,多个条件是&&
的关系,必须都满足
- 可以为函数
options
:配置项,可选,对象类型,不支持基础配置项itemKey
:指定节点key
名,默认值为id
childrenKey
:自定义子节点key
名,默认值为children
parentKey
:自定义父节点key
名,默认值为parentId
root
:顶层标识配置levelKey
:节点层级key
配置leafKey
:叶子节点key
配置
js
import { toTree } from 'kk-utils-library/tree';
const data = [
{
id: '1',
name: '1'
},
{
id: '2',
name: '2',
parentId: '1'
},
{
id: '3',
name: '3',
parentId: '1'
},
{
id: '4',
name: '4',
parentId: '2'
},
{
id: '5',
name: '5'
}
];
const result = toTree(data);
console.log('result', result);
// [
// {
// id: '1',
// name: '1',
// children: [
// {
// id: '2',
// name: '2',
// parentId: '1',
// children: [
// {
// id: '4',
// name: '4',
// parentId: '2',
// children: null,
// level: 3,
// isLeaf: true
// }
// ],
// level: 2,
// isLeaf: false
// },
// {
// id: '3',
// name: '3',
// parentId: '1',
// children: null,
// level: 2,
// isLeaf: true
// }
// ],
// level: 1,
// isLeaf: false
// },
// {
// id: '5',
// name: '5',
// children: null,
// level: 1,
// isLeaf: true
// }
// ];
getDepthAndLength
获取树结构的深度和最长子级长度
js
getDepthAndLength(tree, [options])
tree
:树形数组options
:配置项,可选,对象类型,支持基础配置项
js
import { getDepthAndLength } from 'kk-utils-library/tree';
const data = [
{
key: 1,
children: [
{
key: 11,
children: [
{
key: 99
},
{
key: 112
}
]
},
{
key: 12,
children: [
{
key: 122,
children: [
{
key: 1221
},
{
key: 1222
}
]
}
]
}
]
}
];
const result = getDepthAndLength(data);
console.log('result', result);
// { "depth": 3, "length": 2 } // 深度和最长子级数量
fixParentId
给树形数组每一项补上parentId
js
fixParentId(array, [options])
array
:数组options
:配置项,可选,对象类型,不支持基础配置项itemKey
:指定节点key
名,默认值为id
childrenKey
:自定义子节点key
名,默认值为children
parentKey
:自定义父节点key
名,默认值为parentId
js
import { fixParentId } from 'kk-utils-library/tree';
const data = [
{
id: 1,
children: [
{
id: 11,
children: [
{
id: 99
},
{
id: 112
}
]
},
{
id: 12,
children: [
{
id: 122,
children: [
{
id: 1221
},
{
id: 1222
}
]
}
]
}
]
}
];
const result = fixParentId(data);
console.log('result', result);
// [
// {
// id: 1,
// children: [
// {
// id: 11,
// children: [
// {
// id: 99,
// parentId: 11
// },
// {
// id: 112,
// parentId: 11
// }
// ],
// parentId: 1
// },
// {
// id: 12,
// children: [
// {
// id: 122,
// children: [
// {
// id: 1221,
// parentId: 122
// },
// {
// id: 1222,
// parentId: 122
// }
// ],
// parentId: 12
// }
// ],
// parentId: 1
// }
// ]
// }
// ];
findAncestor
从树形数组里根据传入的节点ID
查找出它的所有祖先元素,返回一个有层级关系的tree
数据
js
findAncestor(array, [options])
array
:数组options
:配置项,可选,对象类型,不支持基础配置项root
顶层标识配置itemKey
:指定节点key
名,默认值为id
childrenKey
:自定义子节点key
名,默认值为children
parentKey
:自定义父节点key
名,默认值为parentId
withChildren
:是否携带子级数据,默认为false
js
import { findAncestor } from 'kk-utils-library/tree';
const data = [
{
id: 1,
children: [
{
id: 11,
children: [
{
id: 99,
parentId: 11
},
{
id: 112,
parentId: 11
}
],
parentId: 1
},
{
id: 12,
children: [
{
id: 122,
children: [
{
id: 1221,
parentId: 122
},
{
id: 1222,
parentId: 122
}
],
parentId: 12
}
],
parentId: 1
}
]
}
];
const result = findAncestor(data, 1221);
console.log('result', result);
// {
// id: 1,
// children: [
// {
// id: 12,
// children: [
// {
// id: 122,
// children: [
// {
// id: 1221,
// parentId: 122
// }
// ],
// parentId: 12
// }
// ],
// parentId: 1
// }
// ]
// }