Skip to content

Commit cda325c

Browse files
committed
docs: zh guide & api
1 parent c322794 commit cda325c

File tree

2 files changed

+339
-6
lines changed

2 files changed

+339
-6
lines changed

docs/zh/v1/api.md

Lines changed: 334 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,338 @@
11
# API
22

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+
```
4161

5162
## 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 | 是否可拖动 |

docs/zh/v1/guide.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ export default function App() {
7474
- `idKey, parentIdKey`, 默认值是`id``parent_id`. 使用扁平数据时需要. 虽然有默认值, 但还是建议写明更好.
7575
- `childrenKey`, 默认是`children`. 使用树形数据时需要. 虽然有默认值, 但还是建议写明更好.
7676
- `onChange`, 数据改变时调用的函数, 参数是新数据. 如果你的树不会改变则不需要.
77-
- `isFunctionReactive`, 布尔. 默认`false`. `useHeTree`选项中包含许多回调函数, 如`onChange, canDrop`. `isFunctionReactive`可用来控制是否监听这些回调函数的改变. 如果你的回调函数和`data`是同步改变的, 则不用启用此项. 否则你需要启用此项, 并且用 React 的`useCallback``useMemo`缓存你的所有回调函数以避免性能问题.
77+
- <a id="isfunctionreactive"/>`isFunctionReactive`, 布尔. 默认`false`. `useHeTree`选项中包含许多回调函数, 如`onChange, canDrop`. `isFunctionReactive`可用来控制是否监听这些回调函数的改变. 如果你的回调函数和`data`是同步改变的, 则不用启用此项. 否则你需要启用此项, 并且用 React 的`useCallback``useMemo`缓存你的所有回调函数以避免性能问题.
7878

7979
[查看`useHeTree`的 API 文档以了解更多](api#usehetree).
8080

@@ -103,7 +103,7 @@ export default function App() {
103103
<<< @/../src/pages/custom_drag_trigger_flat_data.tsx{14}
104104
<DemoIframe url="/custom_drag_trigger_flat_data" />
105105

106-
## 节点 HTML 结构和样式
106+
## 节点 HTML 结构和样式<a id="node_structure_style"/>
107107

108108
节点 HTML 如下:
109109

@@ -145,7 +145,7 @@ renderNodeBox: ({ stat, attrs, isPlaceholder }) => (
145145
<<< @/../src/pages/customize_placeholder_and_node_box.tsx{13-19,23-39}
146146
<DemoIframe url="/customize_placeholder_and_node_box" />
147147

148-
## 节点的展开与折叠
148+
## 节点的展开与折叠<a id="node_open"/>
149149

150150
- 使用选项`openIds`表明展开的节点.
151151
- 可通过`stat.open`获取该节点的`open`状态.
@@ -156,7 +156,7 @@ renderNodeBox: ({ stat, attrs, isPlaceholder }) => (
156156
<DemoIframe url="/open_ids" />
157157
此例子顶部 4 个按钮分别是: 展开全部, 折叠全部, 展开'Python'节点的所有父节点, 仅展开'Python'节点的所有父节点.
158158

159-
## 节点的勾选
159+
## 节点的勾选<a id="node_checked"/>
160160

161161
- 使用选项`checkedIds`表明勾选的节点.
162162
- 可通过`stat.checked`获取该节点的`checked`状态.
@@ -213,7 +213,7 @@ yarn add immer use-immer
213213

214214
:::
215215

216-
## 使用内置方法更新扁平数据
216+
## 使用内置方法更新扁平数据<a id="update_flat_data_with_inner_methods2"/>
217217

218218
[`addToFlatData`](api#addtoflatdata): 增加节点. [`removeByIdInFlatData`](api#removebyidinflatdata): 删除节点.
219219
这两个方法都会改变原数据, 所以把原数据的复制传给它, 或者与`immer`一起使用.

0 commit comments

Comments
 (0)