API
导出
此库导出的变量, 方法, Typescript 类型.
useHeTree: 主要的 React hook. 本库没有导出组件, 你需要使用此函数返回的renderTree渲染树.walkTreeData,walkTreeDataGenerator,findTreeData,filterTreeData,openParentsInTreeData,updateCheckedInTreeData: 用来处理和遍历树形数据的方法.sortFlatData,walkFlatData,walkFlatDataGenerator,convertIndexToTreeIndexInFlatData,addToFlatData,removeByIdInFlatData,openParentsInFlatData,updateCheckedInFlatData: 用来处理和遍历扁平数据的方法.walkParentsGenerator: 遍历另一种特殊数据的方法. 这种数据类似HTMLElement, 其中包含类似于parentElement的指向父节点的键.defaultProps:useHeTree的选项的默认值.
以下为 Typescript 的类型:
Id: 节点 id, 父级 id. 类型:string | number.Stat: 节点的相关信息.HeTreeProps:useHeTree的选项.
useHeTree
import { useHeTree } from "he-tree-react";
const {/* return */} = useHeTree({/* options */}) // prettier-ignore本库的主要功能. React hook. 参数如下:
options: 选项, 类型是对象. 以下是 options 中的部分属性:
名称 类型 默认值 描述 data Array 数据. 参考数据类型. dataType 'flat', 'tree' 'flat' 数据类型 idKey string 'id' 你的数据中 id 的键名. parentIdKey string 'parent_id' 你的数据中父级 id 的键名. 仅用于扁平数据. childrenKey string 'children' 你的数据中子级的键名. 仅用于树形数据. indent number 20 节点缩进, 单位是 px. dragOpen boolean false 是否启用功能"拖拽到节点上时打开节点". dragOpenDelay number 600 拖拽到节点上时打开节点的等待时间. 单位是毫秒. onDragOpen function(stat): void拖拽到节点上时打开节点的回调. direction 'lrt', 'rtl' 'ltr' 显示方向, ltr 是从左往右显示, rtl 与之相反. rootId string, null null 使用扁平数据时, 没有父级的节点的父级 id. virtual boolean false 是否启用虚拟化. 当数据非常多时用来提高性能. keepPlaceholder boolean false 当拖拽离开树的范围, 是否要保留占位元素. 建议只在一个树的页面开启此项. openIds Array 所有打开节点的 id. checkedIds Array 所有勾选的节点的 id. isFunctionReactive boolean false 是否监听回调函数的改变. 参考 以下是 options 中的剩余回调方法:
名称 类型 描述 renderNode (stat)=> ReactNode节点的渲染函数. renderNodeBox ({stat, attrs, isPlaceholder})=> ReactNodenodeBox 的渲染函数. 参考. onChange (newData)=>void数据发生改变时调用. canDrag (stat)=>boolean, null, undefined, void节点是否可拖拽. 返回 null, undefined, void表示继承父节点.canDrop (stat, index)=>boolean, null, undefined, void节点是否可放入. 返回 null, undefined, void表示继承父节点. 参数index可能为空, 不为空时表示将要放入节点的子级的位置.customDragImage (event, stat)=> void调用 event.dataTransfer.setDragImage自定义 drag image. 参考.onDragStart (event, stat)=> void当拖拽开始时 onExternalDragOver (event)=>boolean当拖拽来自外部时调用. 你必选返回布尔值表示是否处理此拖拽. onDragOver (event, stat, isExternal)=> void当拖拽到树上方时, isExternal表示此次拖拽是否来自外部.onDragEnd (event, stat, isOutside)=>void当此树发起的拖拽结束时调用. stat 是此次拖拽的节点的 stat.isOutside 表示是否在树外部结束. onExternalDrop (event, parentStat, index)=>void当外部拖拽在此树结束时调用. parentStat 是目标父节点的 stat, 为空时代表树的根级. index 是目标位置, 即节点在兄弟节点中的索引.
useHeTree的返回
useHeTree的返回是对象, 包含了一些 states 和方法. 注意, 这个对象每次更新都会改变, 不要依赖这个对象, 可以依赖这个对象的属性. 属性如下:
| 名称 | 类型 | 描述 |
|---|---|---|
| renderTree | (options?: { className?: string, style?: React.CSSProperties }): ReactNode | 渲染树. 参数可以传入className和style控制根元素的样式. |
| getStat | (idOrNodeOrStat)=>stat | 根据 id, 节点数据或 stat, 获得对应的 stat. |
| allIds | 数组 | 所有节点的 id. |
| rootIds | 数组 | 树根级的所有节点的 id. |
| rootNodes | 数组 | 树根级的所有节点的数据. 如果是树形数据, 它就是选项中的data. |
| rootStats | 数组 | 树根级的所有节点的 stat. |
| placeholder | {parentStat, index, level} | 拖拽时占位节点的信息. 占位节点不存在时为空. |
| draggingStat | stat | 由此树发起拖拽时, 被拖拽的节点的 stat. 不存在时为空. |
| dragOverStat | stat | 拖拽到其上面的节点. 可能为空. |
| visibleIds | 数组 | 显示的所有节点的 id. |
| attrsList | 数组 | 显示的所有节点的 attrs. |
| virtualListRef | ref | 虚拟列表组件的 ref, 参考虚拟列表. |
| scrollToNode | (idOrNodeOrStat)=>boolean | 滚动到节点. 参数可以是 id, 节点数据或 stat. 如果节点未找到或未显示, 返回false. 例子 |
walkTreeDataGenerator
通过for of遍历树形数据的方法. 循环中执行skipChildren()将跳过该节点的所有子节点, 执行exitWalk将结束遍历.
for (const [
node,
{ parent, parents, siblings, index, skipChildren, exitWalk },
] of walkTreeDataGenerator(data, "children")) {
// ...
}walkTreeData
通过回调方法遍历树形数据的方法. 回调方法中执行skipChildren()将跳过该节点的所有子节点, 执行exitWalk将结束遍历.
walkTreeDataGenerator(
data,
(node, { parent, parents, siblings, index, skipChildren, exitWalk }) => {
// ...
},
"children"
);findTreeData
类似 Array.prototype.find. 返回找到的第一个节点. 回调方法中执行skipChildren()将跳过该节点的所有子节点, 执行exitWalk将结束遍历.
let foundNode = findTreeData(
data,
(node, { parent, parents, siblings, index, skipChildren, exitWalk }) => {
// return node.id === 1;
},
"children"
);filterTreeData
类似 Array.prototype.filter. 返回找到的所有节点. 回调方法中执行skipChildren()将跳过该节点的所有子节点, 执行exitWalk将结束遍历.
let nodes = filterTreeData(
data,
(node, { parent, parents, siblings, index, skipChildren, exitWalk }) => {
// return node.id > 1;
},
"children"
);openParentsInTreeData
打开单个或多个节点的所有父节点, 这样才能确保该节点可见. 参考.
(
treeData,
openIds: Id[],
idOrIds: Id | Id[],
options?: {idKey: string, childrenKey: string}
): newOpenIdsupdateCheckedInTreeData
更新单个节点或多个节点的checked状态. 这将同时更新它们的子节点和父节点. 参考.
(
treeData,
checkedIds: Id[],
idOrIds: Id | Id[],
checked: boolean,
options?: {idKey: string, childrenKey: string}
): [newCheckedIds, newSemiCheckedIds]sortFlatData
把扁平数据按照节点在树里的顺序排序. 返回排序后的新数组. 你的数据在初始化时应该使用它以保证顺序.
(
flatData,
options?: {idKey: string, parentIdKey: string}
): sortedDatawalkFlatDataGenerator
通过for of遍历扁平数据的方法. 循环中执行skipChildren()将跳过该节点的所有子节点, 执行exitWalk将结束遍历. 使用前需确保你的数据的顺序是正确的.
相比于walkTreeDataGenerator, 少了siblings, 多了 treeIndex, id, pid. treeIndex是节点在整个树中的索引.
for (const [
node,
{ parent, parents, index, treeIndex, id, pid, skipChildren, exitWalk },
] of walkFlatDataGenerator(flatData, {
idKey: "id",
parentIdKey: "parent_id",
})) {
// ...
}walkFlatData
通过回调方法遍历扁平数据的方法. 回调方法中执行skipChildren()将跳过该节点的所有子节点, 执行exitWalk将结束遍历. 使用前需确保你的数据的顺序是正确的.
walkFlatData(
flatData,
(
node,
{ parent, parents, index, treeIndex, id, pid, skipChildren, exitWalk }
) => {
// ...
},
{
idKey: "id",
parentIdKey: "parent_id",
}
);openParentsInFlatData
打开单个或多个节点的所有父节点, 这样才能确保该节点可见. 用前需确保你的数据的顺序是正确的. 参考.
(
flatData,
openIds: Id[],
idOrIds: Id | Id[],
options?: {
idKey: "id",
parentIdKey: "parent_id",
}
): newOpenIdsupdateCheckedInFlatData
更新单个节点或多个节点的checked状态. 这将同时更新它们的子节点和父节点. 用前需确保你的数据的顺序是正确的. 参考.
(
flatData,
checkedIds: Id[],
idOrIds: Id | Id[],
checked: boolean,
options?: {
idKey: "id",
parentIdKey: "parent_id",
}
): [newCheckedIds, newSemiCheckedIds]convertIndexToTreeIndexInFlatData
通过某节点的父节点 id 和它在兄弟节点中的索引, 计算出它在整棵树中的索引.
(
flatData,
parentId: Id | null,
indexInSiblings: Id | null,
options?: {
idKey: "id",
parentIdKey: "parent_id",
}
): treeIndexaddToFlatData
向扁平数据添加一个节点. 它会改变原数据数组. 所以推荐传入原始数据的拷贝, 或者与useImmer一起使用. 参考
(
flatData,
newNode,
index: Id | null,
options?: {
idKey: "id",
parentIdKey: "parent_id",
}
):voidremoveByIdInFlatData
从扁平数据删除一个节点. 返回被删除的数据. 它会改变原数据数组. 所以推荐传入原始数据的拷贝, 或者与useImmer一起使用. 参考
(
flatData,
removeId: Id | null,
options?: {
idKey: "id",
parentIdKey: "parent_id",
}
): removedDatawalkParentsGenerator
遍历另一种特殊数据的方法. 这种数据类似HTMLElement, 其中包含类似于parentElement的指向父节点的键.
(
node,
parentKeyOrGetter: string | ((node) => parent | undefined),
options?: {
withSelf: boolean;
}
): GeneratorparentKeyOrGetter可以是字符串或者返回父级的方法. options.withSelf表示是否包括传入的节点. 返回 Generator. 下面是遍历 HTMLElement 的例子:
let el = document.querySelector("div");
for (const parent of walkParentsGenerator(el, "parentElement", {
withSelf: true,
})) {
// ...
}Stat
stat包括和节点有关的信息. 只读. 属性如下:
| 名称 | 类型 | 描述 |
|---|---|---|
| _isStat | boolean | 表明是否是 stat 对象 |
| node | object | 节点的数据 |
| id | Id | id |
| pid | Id, null | 节点的父级 id |
| parent | object, null | 父节点的数据 |
| parentStat | stat, null | 父节点的 stat |
| childIds | Id[] | 子节点的 id 数组 |
| children | object[] | 子节点数组 |
| childStats | stat[] | 子节点的 stat 数组 |
| siblingIds | Id[] | 兄弟节点的 id 数组 |
| siblings | object[] | 兄弟节点数组 |
| siblingStats | stat[] | 兄弟节点的 stat 数组 |
| index | number | 节点在兄弟节点中的索引 |
| level | number | 节点在树中的深度. 从 1 开始 |
| open | boolean | 是否展开 |
| checked | boolean | 是否勾选 |
| draggable | boolean | 是否可拖动 |