|
1 | 1 | # API
|
2 | 2 |
|
3 |
| -<div style="height:900px"></div> |
| 3 | +## 导出 |
| 4 | + |
| 5 | +此库导出的变量, 方法, Typescript 类型. |
| 6 | + |
| 7 | +- [`useHeTree`](#usehetree): 主要的 React hook. 本库没有导出组件, 你需要使用此函数返回的[`renderTree`](#rendertree)渲染树. |
| 8 | +- [`walkTreeData`](#walktreedata), [`walkTreeDataGenerator`](#walktreedatagenerator), [`findTreeData`](#findtreedata), [`filterTreeData`](#filtertreedata), [`openParentsInTreeData`](#openparentsintreedata), [`updateCheckedInTreeData`](#updatecheckedintreedata): 用来处理和遍历树形数据的方法. |
| 9 | +- [`sortFlatData`](#sortflatdata), [`walkFlatData`](#walkflatdata), [`walkFlatDataGenerator`](#walkflatdatagenerator), [`convertIndexToTreeIndexInFlatData`](#convertindextotreeindexinflatdata), [`addToFlatData`](#addtoflatdata), [`removeByIdInFlatData`](#removebyidinflatdata), [`openParentsInFlatData`](#openparentsinflatdata), [`updateCheckedInFlatData`](#updatecheckedinflatdata): 用来处理和遍历扁平数据的方法. |
| 10 | +- [`walkParentsGenerator`](#walkparentsgenerator): 遍历另一种特殊数据的方法. 这种数据类似`HTMLElement`, 其中包含类似于`parentElement`的指向父节点的键. |
| 11 | +- `defaultProps`: `useHeTree`的选项的默认值. |
| 12 | + |
| 13 | +以下为 Typescript 的类型: |
| 14 | + |
| 15 | +- `Id`: 节点 id, 父级 id. 类型: `string | number`. |
| 16 | +- [`Stat`](#stat): 节点的相关信息. |
| 17 | +- `HeTreeProps`: `useHeTree`的选项. |
| 18 | + |
| 19 | +## useHeTree |
| 20 | + |
| 21 | +```ts |
| 22 | +import { useHeTree } from "he-tree-react"; |
| 23 | +const {/* return */} = useHeTree({/* options */}) // prettier-ignore |
| 24 | +``` |
| 25 | + |
| 26 | +本库的主要功能. React hook. 参数如下: |
| 27 | + |
| 28 | +- options: 选项, 类型是对象. 以下是 options 中的部分属性: |
| 29 | + |
| 30 | + | 名称 | 类型 | 默认值 | 描述 | |
| 31 | + | ---------------------------------------------- | ----------------------- | ----------- | :-------------------------------------------------------------------- | |
| 32 | + | data<a id="data"/> | Array | | 数据. 参考[数据类型](guide#数据类型). | |
| 33 | + | dataType<a id="datatype"/> | 'flat', 'tree' | 'flat' | 数据类型 | |
| 34 | + | idKey<a id="idkey"/> | string | 'id' | 你的数据中 id 的键名. | |
| 35 | + | parentIdKey<a id="parentidkey"/> | string | 'parent_id' | 你的数据中父级 id 的键名. 仅用于扁平数据. | |
| 36 | + | childrenKey<a id="childrenkey"/> | string | 'children' | 你的数据中子级的键名. 仅用于树形数据. | |
| 37 | + | indent<a id="indent"/> | number | 20 | 节点缩进, 单位是 px. | |
| 38 | + | dragOpen<a id="dragopen"/> | boolean | false | 是否启用功能"拖拽到节点上时打开节点". | |
| 39 | + | dragOpenDelay<a id="dragopendelay"/> | number | 600 | 拖拽到节点上时打开节点的等待时间. 单位是毫秒. | |
| 40 | + | onDragOpen<a id="ondragopen"/> | `function(stat): void` | | 拖拽到节点上时打开节点的回调. | |
| 41 | + | direction<a id="direction"/> | 'lrt', 'rtl' | 'ltr' | 显示方向, ltr 是从左往右显示, rtl 与之相反. | |
| 42 | + | rootId<a id="rootid"/> | string, null | null | 使用扁平数据时, 没有父级的节点的父级 id. | |
| 43 | + | virtual<a id="virtual"/> | boolean | false | 是否启用虚拟化. 当数据非常多时用来提示性能. | |
| 44 | + | keepPlaceholder<a id="keepplaceholder"/> | boolean | false | 当拖拽离开树的范围, 是否要保留占位元素. 建议只在一个树的页面开启此项. | |
| 45 | + | openIds<a id="openids"/> | Array | | 所有打开节点的 id. | |
| 46 | + | checkedIds<a id="checkedids"/> | Array | | 所有勾选的节点的 id. | |
| 47 | + | isFunctionReactive<a id="isfunctionreactive"/> | boolean | false | 是否监听回调函数的改变. [参考] | |
| 48 | + |
| 49 | + 以下是 options 中的剩余回调方法: |
| 50 | + | 名称 | 类型 | 描述 | |
| 51 | + | ------------------------- | ------------------------------------------------------ | :-------------------------------------------------------------------------------------------------------------------------------------------| |
| 52 | + | renderNode<a id="rendernode"/> | `(stat)=> ReactNode` | 节点的渲染函数. | |
| 53 | + | renderNodeBox<a id="rendernodebox"/> | `({stat, attrs, isPlaceholder})=> ReactNode` | nodeBox 的渲染函数. [参考](guide#node_structure_style). | |
| 54 | + | onChange<a id="onchange"/>| `(newData)=>void`|数据发生改变时调用.| |
| 55 | + | canDrag<a id="candrag"/> | `(stat)=>boolean, null, undefined, void` | 节点是否可拖拽. 返回`null, undefined, void`表示继承父节点. | |
| 56 | + | canDrop<a id="candrop"/> | `(stat, index)=>boolean, null, undefined, void` | 节点是否可放入. 返回`null, undefined, void`表示继承父节点. 参数`index`可能为空, 不为空时表示将要放入节点的子级的位置. | |
| 57 | + | customDragImage<a id="customdragimage"/> | `(event, stat)=> void` | 调用`event.dataTransfer.setDragImage`自定义 drag image. [参考](#https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/setDragImage). | |
| 58 | + |onDragStart<a id="ondragstart"/>| `(event, stat)=> void` |当拖拽开始时| |
| 59 | + |onExternalDragOver<a id="onexternaldragover"/>|`(event)=>boolean`|当拖拽来自外部时调用. 你必选返回布尔值表示是否处理此拖拽.| |
| 60 | + |onDragOver<a id="ondragover"/>| `(event, stat, isExternal)=> void` |当拖拽到树上方时, `isExternal`表示此次拖拽是否来自外部.| |
| 61 | + |onDragEnd<a id="ondragend"/>|`(event, stat, isOutside)=>void`|当此树发起的拖拽结束时调用. stat 是此次拖拽的节点的 stat.isOutside 表示是否在树外部结束.| |
| 62 | + |onExternalDrop<a id="onexternaldrop"/>|`(event, parentStat, index)=>void`|当外部拖拽在此树结束时调用. parentStat 是目标父节点的 stat, 为空时代表树的根级. index 是目标位置, 即节点在兄弟节点中的索引.| |
| 63 | + |
| 64 | +`useHeTree`的返回是对象, 包含了一些 states 和方法. **注意**, 这个对象每次更新都会改变, 不要依赖这个对象, 可以依赖这个对象的属性. 属性如下: |
| 65 | +| 名称 | 类型 | 描述 | |
| 66 | +| ------------------------- | ------------------------------------------------------ | :-------------------------------------------------------------------------------------------------------------------------------------------| |
| 67 | +|renderHeTree<a id="renderhetree"/>|`(options?: { className?: string, style?: React.CSSProperties }): ReactNode`|渲染树. 参数可以传入`className`和`style`控制根元素的样式.| |
| 68 | +|getStat<a id="getstat"/>|`(idOrNodeOrStat)=>stat`|根据 id, 节点数据或 stat, 获得对应的 stat.| |
| 69 | +|allIds<a id="allids"/>|数组|所有节点的 id.| |
| 70 | +|rootIds<a id="rootids"/>|数组|树根级的所有节点的 id.| |
| 71 | +|rootNodes<a id="rootnodes"/>|数组|树根级的所有节点的数据. 如果是树形数据, 它就是选项中的`data`.| |
| 72 | +|rootStats<a id="rootstats"/>|数组|树根级的所有节点的 stat.| |
| 73 | +|placeholder<a id="placeholder"/>|`{parentStat, index, level}`| 拖拽时占位节点的信息. 占位节点不存在时为空.| |
| 74 | +|draggingStat<a id="draggingstat"/>|`stat`|由此树发起拖拽时, 被拖拽的节点的 stat. 不存在时为空.| |
| 75 | +|dragOverStat<a id="dragoverstat"/>|`stat`|拖拽到其上面的节点. 可能为空.| |
| 76 | +|visibleIds<a id="visibleids"/>|数组|显示的所有节点的 id.| |
| 77 | +|attrsList<a id="attrslist"/>|数组|显示的所有节点的 attrs.| |
| 78 | +|virtualListRef<a id="virtuallistref"/>|`ref`|虚拟列表组件的 ref, 参考[虚拟列表](https://github.com/phphe/react-base-virtual-list).| |
| 79 | + |
| 80 | +## walkTreeDataGenerator |
| 81 | + |
| 82 | +通过`for of`遍历树形数据的方法. 循环中执行`skipChildren()`将跳过该节点的所有子节点, 执行`exitWalk`将结束遍历. |
| 83 | + |
| 84 | +```ts |
| 85 | +for (const [ |
| 86 | + node, |
| 87 | + { parent, parents, siblings, index, skipChildren, exitWalk }, |
| 88 | +] of walkTreeDataGenerator(data, "children")) { |
| 89 | + // ... |
| 90 | +} |
| 91 | +``` |
| 92 | + |
| 93 | +## walkTreeData |
| 94 | + |
| 95 | +通过回调方法遍历树形数据的方法. 回调方法中执行`skipChildren()`将跳过该节点的所有子节点, 执行`exitWalk`将结束遍历. |
| 96 | + |
| 97 | +```ts |
| 98 | +walkTreeDataGenerator( |
| 99 | + data, |
| 100 | + (node, { parent, parents, siblings, index, skipChildren, exitWalk }) => { |
| 101 | + // ... |
| 102 | + }, |
| 103 | + "children" |
| 104 | +); |
| 105 | +``` |
| 106 | + |
| 107 | +## findTreeData |
| 108 | + |
| 109 | +类似 `Array.prototype.find`. 返回找到的第一个节点. 回调方法中执行`skipChildren()`将跳过该节点的所有子节点, 执行`exitWalk`将结束遍历. |
| 110 | + |
| 111 | +```ts |
| 112 | +let foundNode = findTreeData( |
| 113 | + data, |
| 114 | + (node, { parent, parents, siblings, index, skipChildren, exitWalk }) => { |
| 115 | + // return node.id === 1; |
| 116 | + }, |
| 117 | + "children" |
| 118 | +); |
| 119 | +``` |
| 120 | + |
| 121 | +## filterTreeData |
| 122 | + |
| 123 | +类似 `Array.prototype.filter`. 返回找到的所有节点. 回调方法中执行`skipChildren()`将跳过该节点的所有子节点, 执行`exitWalk`将结束遍历. |
| 124 | + |
| 125 | +```ts |
| 126 | +let nodes = filterTreeData( |
| 127 | + data, |
| 128 | + (node, { parent, parents, siblings, index, skipChildren, exitWalk }) => { |
| 129 | + // return node.id > 1; |
| 130 | + }, |
| 131 | + "children" |
| 132 | +); |
| 133 | +``` |
| 134 | + |
| 135 | +## openParentsInTreeData |
| 136 | + |
| 137 | +打开单个或多个节点的所有父节点, 这样才能确保该节点可见. [参考](guide#node_open). |
| 138 | + |
| 139 | +``` |
| 140 | +( |
| 141 | + treeData, |
| 142 | + openIds: Id[], |
| 143 | + idOrIds: Id | Id[], |
| 144 | + options?: {idKey: string, childrenKey: string} |
| 145 | +): newOpenIds |
| 146 | +``` |
| 147 | + |
| 148 | +## updateCheckedInTreeData |
| 149 | + |
| 150 | +更新单个节点或多个节点的`checked`状态. 这将同时更新它们的子节点和父节点. [参考](guide#node_checked). |
| 151 | + |
| 152 | +``` |
| 153 | +( |
| 154 | + treeData, |
| 155 | + checkedIds: Id[], |
| 156 | + idOrIds: Id | Id[], |
| 157 | + checked: boolean, |
| 158 | + options?: {idKey: string, childrenKey: string} |
| 159 | +): [newCheckedIds, newSemiCheckedIds] |
| 160 | +``` |
4 | 161 |
|
5 | 162 | ## sortFlatData
|
| 163 | + |
| 164 | +把扁平数据按照节点在树里的顺序排序. 返回排序后的新数组. 你的数据在初始化时应该使用它以保证顺序. |
| 165 | + |
| 166 | +``` |
| 167 | +( |
| 168 | + flatData, |
| 169 | + options?: {idKey: string, parentIdKey: string} |
| 170 | +): sortedData |
| 171 | +``` |
| 172 | + |
| 173 | +## walkFlatDataGenerator |
| 174 | + |
| 175 | +通过`for of`遍历扁平数据的方法. 循环中执行`skipChildren()`将跳过该节点的所有子节点, 执行`exitWalk`将结束遍历. 使用前需确保你的数据的顺序是正确的. |
| 176 | + |
| 177 | +相比于`walkTreeDataGenerator`, 少了`siblings`, 多了 `treeIndex, id, pid`. `treeIndex`是节点在整个树中的索引. |
| 178 | + |
| 179 | +```ts |
| 180 | +for (const [ |
| 181 | + node, |
| 182 | + { parent, parents, index, treeIndex, id, pid, skipChildren, exitWalk }, |
| 183 | +] of walkFlatDataGenerator(flatData, { |
| 184 | + idKey: "id", |
| 185 | + parentIdKey: "parent_id", |
| 186 | +})) { |
| 187 | + // ... |
| 188 | +} |
| 189 | +``` |
| 190 | + |
| 191 | +## walkFlatData |
| 192 | + |
| 193 | +通过回调方法遍历扁平数据的方法. 回调方法中执行`skipChildren()`将跳过该节点的所有子节点, 执行`exitWalk`将结束遍历. 使用前需确保你的数据的顺序是正确的. |
| 194 | + |
| 195 | +```ts |
| 196 | +walkFlatData( |
| 197 | + flatData, |
| 198 | + ( |
| 199 | + node, |
| 200 | + { parent, parents, index, treeIndex, id, pid, skipChildren, exitWalk } |
| 201 | + ) => { |
| 202 | + // ... |
| 203 | + }, |
| 204 | + { |
| 205 | + idKey: "id", |
| 206 | + parentIdKey: "parent_id", |
| 207 | + } |
| 208 | +); |
| 209 | +``` |
| 210 | + |
| 211 | +## openParentsInFlatData |
| 212 | + |
| 213 | +打开单个或多个节点的所有父节点, 这样才能确保该节点可见. 用前需确保你的数据的顺序是正确的. [参考](guide#node_open). |
| 214 | + |
| 215 | +``` |
| 216 | +( |
| 217 | + flatData, |
| 218 | + openIds: Id[], |
| 219 | + idOrIds: Id | Id[], |
| 220 | + options?: { |
| 221 | + idKey: "id", |
| 222 | + parentIdKey: "parent_id", |
| 223 | + } |
| 224 | +): newOpenIds |
| 225 | +``` |
| 226 | + |
| 227 | +## updateCheckedInFlatData |
| 228 | + |
| 229 | +更新单个节点或多个节点的`checked`状态. 这将同时更新它们的子节点和父节点. 用前需确保你的数据的顺序是正确的. [参考](guide#node_checked). |
| 230 | + |
| 231 | +``` |
| 232 | +( |
| 233 | + flatData, |
| 234 | + checkedIds: Id[], |
| 235 | + idOrIds: Id | Id[], |
| 236 | + checked: boolean, |
| 237 | + options?: { |
| 238 | + idKey: "id", |
| 239 | + parentIdKey: "parent_id", |
| 240 | + } |
| 241 | +): [newCheckedIds, newSemiCheckedIds] |
| 242 | +``` |
| 243 | + |
| 244 | +## convertIndexToTreeIndexInFlatData |
| 245 | + |
| 246 | +通过某节点的父节点 id 和它在兄弟节点中的索引, 计算出它在整棵树中的索引. |
| 247 | + |
| 248 | +``` |
| 249 | +( |
| 250 | + flatData, |
| 251 | + parentId: Id | null, |
| 252 | + indexInSiblings: Id | null, |
| 253 | + options?: { |
| 254 | + idKey: "id", |
| 255 | + parentIdKey: "parent_id", |
| 256 | + } |
| 257 | +): treeIndex |
| 258 | +``` |
| 259 | + |
| 260 | +## addToFlatData |
| 261 | + |
| 262 | +向扁平数据添加一个节点. 它会改变原数据数组. 所以推荐传入原始数据的拷贝, 或者与`useImmer`一起使用. [参考](guide#update_flat_data_with_inner_methods2) |
| 263 | + |
| 264 | +``` |
| 265 | +( |
| 266 | + flatData, |
| 267 | + newNode, |
| 268 | + index: Id | null, |
| 269 | + options?: { |
| 270 | + idKey: "id", |
| 271 | + parentIdKey: "parent_id", |
| 272 | + } |
| 273 | +):void |
| 274 | +``` |
| 275 | + |
| 276 | +## removeByIdInFlatData |
| 277 | + |
| 278 | +从扁平数据删除一个节点. 返回被删除的数据. 它会改变原数据数组. 所以推荐传入原始数据的拷贝, 或者与`useImmer`一起使用. [参考] |
| 279 | + |
| 280 | +``` |
| 281 | +( |
| 282 | + flatData, |
| 283 | + removeId: Id | null, |
| 284 | + options?: { |
| 285 | + idKey: "id", |
| 286 | + parentIdKey: "parent_id", |
| 287 | + } |
| 288 | +): removedData |
| 289 | +``` |
| 290 | + |
| 291 | +## walkParentsGenerator |
| 292 | + |
| 293 | +遍历另一种特殊数据的方法. 这种数据类似`HTMLElement`, 其中包含类似于`parentElement`的指向父节点的键. |
| 294 | + |
| 295 | +``` |
| 296 | +( |
| 297 | + node, |
| 298 | + parentKeyOrGetter: string | ((node) => parent | undefined), |
| 299 | + options?: { |
| 300 | + withSelf: boolean; |
| 301 | + } |
| 302 | +): Generator |
| 303 | +``` |
| 304 | + |
| 305 | +`parentKeyOrGetter`可以是字符串或者返回父级的方法. `options.withSelf`表示是否包括传入的节点. 返回 [Generator](#https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator). 下面是遍历 HTMLElement 的例子: |
| 306 | + |
| 307 | +```ts |
| 308 | +let el = document.querySelector("div"); |
| 309 | +for (const parent of walkParentsGenerator(el, "parentElement", { |
| 310 | + withSelf: true, |
| 311 | +})) { |
| 312 | + // ... |
| 313 | +} |
| 314 | +``` |
| 315 | + |
| 316 | +## Stat |
| 317 | + |
| 318 | +`stat`存储和节点有关的信息. 只读. 属性如下: |
| 319 | + |
| 320 | +| 名称 | 类型 | 描述 | |
| 321 | +| ------------ | ------------ | :-------------------------- | |
| 322 | +| \_isStat | boolean | 表明是否是 stat 对象 | |
| 323 | +| node | object | 节点的数据 | |
| 324 | +| id | Id | id | |
| 325 | +| pid | Id, null | 节点的父级 id | |
| 326 | +| parent | object, null | 父节点的数据 | |
| 327 | +| parentStat | stat, null | 父节点的 stat | |
| 328 | +| childIds | Id[] | 子节点的 id 数组 | |
| 329 | +| children | object[] | 子节点数组 | |
| 330 | +| childStats | stat[] | 子节点的 stat 数组 | |
| 331 | +| siblingIds | Id[] | 兄弟节点的 id 数组 | |
| 332 | +| siblings | object[] | 兄弟节点数组 | |
| 333 | +| siblingStats | stat[] | 兄弟节点的 stat 数组 | |
| 334 | +| index | number | 节点在兄弟节点中的索引 | |
| 335 | +| level | number | 节点在树中的深度. 从 1 开始 | |
| 336 | +| open | boolean | 是否展开 | |
| 337 | +| checked | boolean | 是否勾选 | |
| 338 | +| draggable | boolean | 是否可拖动 | |
0 commit comments