feat(components): [tree-v2] add scrollTo method (#14050)

* feat(components): [tree-v2] add scrollTo method

* docs(components): [tree-v2] scrollTo method

* refactor(components): [tree-v2] rename strollToNode

1. expose scrollTo from listRef

2. rename scrollTo to scrollToNode

3. add test

4. change docs

* docs(components): [tree-v2] add version tag
This commit is contained in:
Kaine 2024-08-02 20:16:32 +08:00 committed by GitHub
parent aceefd7a24
commit 333e1f9c42
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 92 additions and 0 deletions

View File

@ -116,6 +116,8 @@ tree-v2/filter
| expandNode | expand specified node | `(node: TreeNode)` |
| collapseNode | collapse specified node | `(node: TreeNode)` |
| setData | When the data is very large, using reactive data will cause the poor performance, so we provide a way to avoid this situation | `(data: TreeData)` |
| scrollTo ^(2.8.0) | scroll to a given position | `(offset: number)` |
| scrollToNode ^(2.8.0) | scroll to a given tree key with specified scroll strategy | `(key: TreeKey, strategy?: auto \| smart \| center \| start \| end)` |
## TreeV2 Events

View File

@ -1236,5 +1236,70 @@ describe('Virtual Tree', () => {
expect(currentKeys).toBe(0)
expect(nodes[0].classes()).toContain('is-current')
})
test('scrollToNode', async () => {
const { treeVm } = createTree({
data() {
return {
data: [
{
id: 0,
label: 'node-0',
},
{
id: '1',
label: 'node-1',
children: [
{
id: '1-1',
label: 'node-1-1',
children: [
{
id: '1-1-1',
label: 'node-1-1-1',
},
{
id: '1-1-2',
label: 'node-1-1-2',
},
],
},
{
id: '1-2',
label: 'node-1-2',
children: [
{
id: '1-2-1',
label: 'node-1-2-1',
},
],
},
{
id: '1-3',
label: 'node-1-3',
},
],
},
{
id: '2',
label: 'node-2',
},
],
}
},
})
await nextTick()
const scrollToItem = vi.spyOn(treeVm.listRef, 'scrollToItem')
treeVm.scrollToNode('22', 'start')
expect(scrollToItem).not.toHaveBeenCalled()
treeVm.scrollToNode('1', 'start')
expect(scrollToItem).toHaveBeenCalledWith(1, 'start')
})
test('scrollTo', async () => {
const { treeVm } = createTree()
await nextTick()
const scrollTo = vi.spyOn(treeVm.listRef, 'scrollTo')
treeVm.scrollTo(100)
expect(scrollTo).toHaveBeenCalledWith(100)
})
})
})

View File

@ -9,6 +9,10 @@ import {
} from '../virtual-tree'
import { useCheck } from './useCheck'
import { useFilter } from './useFilter'
import type {
FixedSizeList,
Alignment as ScrollStrategy,
} from '@element-plus/components/virtual-list'
import type { SetupContext } from 'vue'
import type { treeEmits } from '../virtual-tree'
import type { CheckboxValueType } from '@element-plus/components/checkbox'
@ -28,6 +32,7 @@ export function useTree(
const expandedKeySet = ref<Set<TreeKey>>(new Set(props.defaultExpandedKeys))
const currentKey = ref<TreeKey | undefined>()
const tree = shallowRef<Tree | undefined>()
const listRef = ref<typeof FixedSizeList | undefined>()
watch(
() => props.currentNodeKey,
@ -278,10 +283,22 @@ export function useTree(
return tree.value?.treeNodeMap.get(key)
}
function scrollToNode(key: TreeKey, strategy: ScrollStrategy = 'auto') {
const node = getNode(key)
if (node && listRef.value) {
listRef.value.scrollToItem(flattenTree.value.indexOf(node), strategy)
}
}
function scrollTo(offset: number) {
listRef.value?.scrollTo(offset)
}
return {
tree,
flattenTree,
isNotEmpty,
listRef,
getKey,
getChildren,
toggleExpand,
@ -310,5 +327,7 @@ export function useTree(
expandNode,
collapseNode,
setExpandedKeys,
scrollToNode,
scrollTo,
}
}

View File

@ -5,6 +5,7 @@
>
<fixed-size-list
v-if="isNotEmpty"
ref="listRef"
:class-name="ns.b('virtual-list')"
:data="flattenTree"
:total="flattenTree.length"
@ -73,6 +74,7 @@ const ns = useNamespace('tree')
const {
flattenTree,
isNotEmpty,
listRef,
toggleExpand,
isExpanded,
isIndeterminate,
@ -99,6 +101,8 @@ const {
expandNode,
collapseNode,
setExpandedKeys,
scrollToNode,
scrollTo,
} = useTree(props, emit)
defineExpose({
@ -118,5 +122,7 @@ defineExpose({
expandNode,
collapseNode,
setExpandedKeys,
scrollToNode,
scrollTo,
})
</script>