Skip to content

feat: add update node APIs #102

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions site/.vitepress/code/ReloadChildren.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<template>
<button @click="handleClearChildren">Clear node-1 children</button>
<button @click="handleSetChildren">Set node-1 children</button>
<button @click="handleUpdateChildren">Update node-1 children</button>
<div :style="{ height: '300px' }">
<VTree ref="tree" checkable selectable />
</div>
</template>

<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import VTree from '@wsfe/vue-tree'

const tree = ref()

const children = Array.from({ length: 100000 }).map((_, i) => {
return {
title: `node-1-${i + 1}`,
id: `node-1-${i + 1}`,
}
})

const data = [
{
title: 'node-1',
id: 'node-1',
children,
},
{
title: 'node-2',
id: 'node-2',
children: [
{
title: 'node-2-1',
id: 'node-2-1',
},
],
},
]

onMounted(() => {
tree.value.setData(data)
})

const handleSetChildren = () => {
tree.value.updateNode('node-1', { children })
}
const handleClearChildren = () => {
tree.value.updateNode('node-1', { children: [] })
}
const handleUpdateChildren = () => {
tree.value.updateNode('node-1', {
children: children.map((child) => {
return {
...child,
title: `${child.title} ${Date.now()}`,
checked: true,
}
})
})
}
</script>

<style scoped>
button {
border: 1px solid lightgray;
border-radius: 8px;
padding-left: 10px;
padding-right: 10px;
margin-right: 20px;
}
</style>
66 changes: 66 additions & 0 deletions site/.vitepress/code/UpdateCustomField.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<template>
<button @click="handleUpdateCount">Update node-1 count</button>
<VTree ref="tree">
<template #node="{ node }">
<span>{{ node.title }}</span>
<span v-if="typeof node.count === 'number'">
Count: {{ node.count }}
</span>
</template>
</VTree>
</template>

<script setup lang="ts">
import { onMounted, ref } from 'vue'
import VTree from '@wsfe/vue-tree'

const tree = ref()

const data = [
{
title: 'node-1',
id: 'node-1',
count: 0,
children: [
{
title: 'node-1-1',
id: 'node-1-1',
},
{
title: 'node-1-2',
id: 'node-1-2',
},
],
},
{
title: 'node-2',
id: 'node-2',
children: [
{
title: 'node-2-1',
id: 'node-2-1',
},
],
},
]

onMounted(() => {
tree.value.setData(data)
})

const handleUpdateCount = () => {
const key = 'node-1'
const currentCount = tree.value.getNode(key).count
tree.value.updateNode(key, { count: currentCount + 1 })
}
</script>

<style scoped>
button {
border: 1px solid lightgray;
border-radius: 8px;
padding-left: 10px;
padding-right: 10px;
margin-right: 20px;
}
</style>
73 changes: 73 additions & 0 deletions site/.vitepress/code/UpdateNodeTitle.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<template>
<button @click="handleUpdateSingleNode">Update node-1</button>
<button @click="handleUpdateMultipleNode">Update node-1 & node-2</button>
<VTree ref="tree" />
</template>

<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import VTree from '@wsfe/vue-tree'

const tree = ref()

const data = [
{
title: 'node-1',
id: 'node-1',
children: [
{
title: 'node-1-1',
id: 'node-1-1',
},
{
title: 'node-1-2',
id: 'node-1-2',
},
],
},
{
title: 'node-2',
id: 'node-2',
children: [
{
title: 'node-2-1',
id: 'node-2-1',
},
],
},
]

onMounted(() => {
tree.value.setData(data)
})

const count = ref(0)

const handleUpdateSingleNode = () => {
count.value++
tree.value.updateNode('node-1', { title: `node-1 - ${count.value}` })
}
const handleUpdateMultipleNode = () => {
count.value++
tree.value.updateNodes([
{
id: 'node-1',
title: `node-1 - ${count.value}`,
},
{
id: 'node-2',
title: `node-2 - ${count.value}`,
},
])
}
</script>

<style scoped>
button {
border: 1px solid lightgray;
border-radius: 8px;
padding-left: 10px;
padding-right: 10px;
margin-right: 20px;
}
</style>
2 changes: 2 additions & 0 deletions site/api/vtree.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@
| filter | 过滤节点 | `keyword: string`: 过滤关键词<br/>`filterMethod: (keyword: string, node: TreeNode) => boolean`: 过滤方法,默认为 filterMethod Prop ,如果没有传 filterMethod Prop 则为搜索 title 字段的一个内置方法 | `void` |
| showCheckedNodes | 展示已选节点 | `showUnloadCheckedNodes: boolean`: 是否显示未加载的选中节点,默认为 Prop 传入的值 | `void` |
| loadRootNodes | 从远程加载根节点 | 无 | `Promise<void>` |
| updateNode `4.1.0` | 更新单个节点 | `key: string \| number`: 节点 key<br/>`newNode: object`: 新节点数据,某些字段将被忽略,例如以下划线 "_" 开头的字段,以及 key 字段和 `indeterminate`, `visible`, `isLeaf` 等 | `void` |
| updateNodes `4.1.0` | 更新多个节点 | `newNodes: object[]`: 新节点数据数组,与 `updateNode` 相同,特定的字段会被忽略,且没有 key 字段的元素将被忽略 | `void` |
| scrollTo | 滚动到指定节点位置 | `key: string \| number`: 节点 key<br/>`verticalPosition: 'top' \| 'center' \| 'bottom' \| number`: 滚动的垂直位置 | `void` |

## VTree Slots
Expand Down
2 changes: 2 additions & 0 deletions site/en/api/vtree.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ Note: Since `2.0.8`, the node info returned in events contains the full node inf
| filter | Filter nodes | `keyword: string`: filter keyword<br/>`filterMethod: (keyword: string, node: TreeNode) => boolean`: filter method, default to filterMethod prop. if filterMethod prop is not present, it's an internal method that searches node title | `void` |
| showCheckedNodes | Show checked nodes | `showUnloadCheckedNodes: boolean`: whether to show checked nodes that are not loaded, default to prop value | `void` |
| loadRootNodes | Load root nodes from remote | None | `Promise<void>` |
| updateNode `4.1.0` | Update single node | `key: string \| number`: node key<br/>`newNode: object`: new node data, some fields will be ignored, like those start with underscore '_', the key field and `indeterminate`, `visible`, `isLeaf`, etc. | `void` |
| updateNodes `4.1.0` | Update multiple nodes | `newNodes: object[]`: new nodes array, some specific fields will be ignored like `updateNode`, and the elements without key field also will be ignored | `void` |
| scrollTo | Scroll to specific node position | `key: string \| number`: node key<br/>`verticalPosition: 'top' \| 'center' \| 'bottom' \| number`: vertical position of scrolling | `void` |

## VTree Slots
Expand Down
20 changes: 20 additions & 0 deletions site/en/examples/node-manipulation.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,23 @@ Enable `draggable` and `droppable`
- Invoke `remove` to remove a node

<CodeDemo component="NodeCreationAndRemoval" />

## Update Node Title {#update-node-title}

Invoke `updateNode` method to update some fields of tree node

Invoke `updateNodes` to update multiple nodes

<CodeDemo component="UpdateNodeTitle" />

## Update Custom Field {#update-custom-field}

Invoke `updateNode` method to update custom fields in tree node

<CodeDemo component="UpdateCustomField" />

## Reload Child Nodes {#reload-children}

Invoke `updateNode` and pass a new `children` list to reload child nodes

<CodeDemo component="ReloadChildren" />
20 changes: 20 additions & 0 deletions site/examples/node-manipulation.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,23 @@
- 调用树组件的 `remove` 方法,可移除节点

<CodeDemo component="NodeCreationAndRemoval" />

## 更新节点名称 {#update-node-title}

调用树组件的 `updateNode` 方法可更新节点部分字段

调用 `updateNodes` 可批量更新

<CodeDemo component="UpdateNodeTitle" />

## 更新自定义字段 {#update-custom-field}

调用树组件的 `updateNode` 方法更新自定义字段

<CodeDemo component="UpdateCustomField" />

## 重新加载子节点 {#reload-children}

调用 `updateNode` 传入新的 `children` 列表可以重新加载子节点

<CodeDemo component="ReloadChildren" />
4 changes: 4 additions & 0 deletions src/components/Tree.vue
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,8 @@ const {
filter,
showCheckedNodes,
loadRootNodes,
updateNode,
updateNodes,
} = usePublicTreeAPI(nonReactive, props, {
resetSpaceHeights,
updateExpandedKeys,
Expand Down Expand Up @@ -705,6 +707,8 @@ defineExpose({
filter,
showCheckedNodes,
loadRootNodes,
updateNode,
updateNodes,
scrollTo,
})

Expand Down
2 changes: 2 additions & 0 deletions src/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ export const TREE_API_METHODS = [
'filter',
'showCheckedNodes',
'loadRootNodes',
'updateNode',
'updateNodes',
'scrollTo'
] as const

Expand Down
14 changes: 14 additions & 0 deletions src/hooks/usePublicTreeAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,18 @@ export const usePublicTreeAPI = (
isRootLoading.value = false
})
}
/**
* 更新单个节点
*/
function updateNode(key: TreeNodeKeyType, newNode: ITreeNodeOptions) {
return nonReactive.store.updateNode(key, newNode)
}
/**
* 更新多个节点
*/
function updateNodes(newNodes: ITreeNodeOptions[]) {
return nonReactive.store.updateNodes(newNodes)
}

return {
unloadCheckedNodes,
Expand Down Expand Up @@ -269,5 +281,7 @@ export const usePublicTreeAPI = (
filter,
showCheckedNodes,
loadRootNodes,
updateNode,
updateNodes,
}
}
Loading
Loading