diff --git a/src/list/_example-ts/virtual-scroll.vue b/src/list/_example-ts/virtual-scroll.vue index 624bf678d6..981988c4bc 100644 --- a/src/list/_example-ts/virtual-scroll.vue +++ b/src/list/_example-ts/virtual-scroll.vue @@ -1,18 +1,39 @@ diff --git a/src/list/_example/virtual-scroll.vue b/src/list/_example/virtual-scroll.vue index 3e13500636..8a99621906 100644 --- a/src/list/_example/virtual-scroll.vue +++ b/src/list/_example/virtual-scroll.vue @@ -1,16 +1,39 @@ + diff --git a/src/list/hooks/useListVirtualScroll.ts b/src/list/hooks/useListVirtualScroll.ts index 3932fcd998..52eaa218c7 100644 --- a/src/list/hooks/useListVirtualScroll.ts +++ b/src/list/hooks/useListVirtualScroll.ts @@ -1,7 +1,9 @@ import { Ref, computed } from 'vue'; + +import log from '../../_common/js/log'; import useVirtualScroll from '../../hooks/useVirtualScrollNew'; import { TdListProps } from '../type'; -import { Styles } from '../../common'; +import { Styles, type ComponentScrollToElementParams } from '../../common'; export const useListVirtualScroll = ( scroll: TdListProps['scroll'], @@ -51,11 +53,26 @@ export const useListVirtualScroll = ( } as Styles), ); + const handleScrollTo = (params: ComponentScrollToElementParams) => { + const { index, key } = params; + const targetIndex = index === 0 ? index : index ?? Number(key); + if (!targetIndex && targetIndex !== 0) { + log.error('List', 'scrollTo: `index` or `key` must exist.'); + return; + } + if (targetIndex < 0 || targetIndex >= listItems.value.length) { + log.error('List', `${targetIndex} does not exist in data, check \`index\` or \`key\` please.`); + return; + } + virtualConfig.scrollToElement({ ...params, index: targetIndex - 1 }); + }; + return { virtualConfig, cursorStyle, listStyle, isVirtualScroll, onInnerVirtualScroll, + scrollToElement: handleScrollTo, }; }; diff --git a/src/list/list.en-US.md b/src/list/list.en-US.md index 236e5a2418..73bb73bca8 100644 --- a/src/list/list.en-US.md +++ b/src/list/list.en-US.md @@ -23,6 +23,13 @@ name | params | description load-more | `(options: { e: MouseEvent })` | \- scroll | `(options: { e: Event \| WheelEvent; scrollTop: number; scrollBottom: number })` | \- +### ListInstanceFunctions + +name | params | return | description +-- | -- | -- | -- +scrollTo | `(scrollToParams: ScrollToElementParams)` | \- | support scrolling to a specific node when virtual scrolling + + ### ListItem Props name | type | default | description | required diff --git a/src/list/list.md b/src/list/list.md index 8d0b14565c..c79e891e30 100644 --- a/src/list/list.md +++ b/src/list/list.md @@ -23,6 +23,13 @@ onScroll | Function | | TS 类型:`(options: { e: Event \| WheelEvent; scroll load-more | `(options: { e: MouseEvent })` | 点击加载更多时触发 scroll | `(options: { e: Event \| WheelEvent; scrollTop: number; scrollBottom: number })` | 列表滚动时触发,scrollTop 表示顶部滚动距离,scrollBottom 表示底部滚动距离 +### ListInstanceFunctions 组件实例方法 + +名称 | 参数 | 返回值 | 描述 +-- | -- | -- | -- +scrollTo | `(scrollToParams: ScrollToElementParams)` | \- | 虚拟滚动场景下,支持指定滚动到具体的节点 + + ### ListItem Props 名称 | 类型 | 默认值 | 说明 | 必传 diff --git a/src/list/list.tsx b/src/list/list.tsx index 212bc11738..6e2f3e5071 100644 --- a/src/list/list.tsx +++ b/src/list/list.tsx @@ -26,11 +26,8 @@ export default defineComponent({ const renderTNodeJSX = useTNodeJSX(); const { listItems } = useListItems(); - const { virtualConfig, cursorStyle, listStyle, isVirtualScroll, onInnerVirtualScroll } = useListVirtualScroll( - props.scroll, - listRef, - listItems, - ); + const { virtualConfig, cursorStyle, listStyle, isVirtualScroll, onInnerVirtualScroll, scrollToElement } = + useListVirtualScroll(props.scroll, listRef, listItems); /** 列表基础逻辑 start */ const listClass = computed(() => { @@ -123,6 +120,7 @@ export default defineComponent({ handleLoadMore, listRef, isVirtualScroll, + scrollTo: scrollToElement, }; }, diff --git a/src/list/type.ts b/src/list/type.ts index ea76e930b9..3c19f27655 100644 --- a/src/list/type.ts +++ b/src/list/type.ts @@ -4,7 +4,7 @@ * 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC * */ -import { TNode, TScroll } from '../common'; +import { TNode, TScroll, ComponentScrollToElementParams } from '../common'; export interface TdListProps { /** @@ -53,6 +53,14 @@ export interface TdListProps { onScroll?: (options: { e: Event | WheelEvent; scrollTop: number; scrollBottom: number }) => void; } +/** 组件实例方法 */ +export interface ListInstanceFunctions { + /** + * 虚拟滚动场景下,支持指定滚动到具体的节点 + */ + scrollTo?: (scrollToParams: ComponentScrollToElementParams) => void; +} + export interface TdListItemProps { /** * 操作栏 diff --git a/test/unit/snap/__snapshots__/csr.test.js.snap b/test/unit/snap/__snapshots__/csr.test.js.snap index 7f2f3bc7f1..22be7741af 100644 --- a/test/unit/snap/__snapshots__/csr.test.js.snap +++ b/test/unit/snap/__snapshots__/csr.test.js.snap @@ -87330,31 +87330,76 @@ exports[`csr snapshot test > csr test ./src/list/_example/stripe.vue 1`] = ` exports[`csr snapshot test > csr test ./src/list/_example/virtual-scroll.vue 1`] = `
- -
- - +
+ + + +
    + + + + +
+ + +
+ +
+ +
+
+
- +
+ + +
+ +
+ + + +
+ +
`; diff --git a/test/unit/snap/__snapshots__/ssr.test.js.snap b/test/unit/snap/__snapshots__/ssr.test.js.snap index 366afb59e7..f46df292db 100644 --- a/test/unit/snap/__snapshots__/ssr.test.js.snap +++ b/test/unit/snap/__snapshots__/ssr.test.js.snap @@ -655,7 +655,7 @@ exports[`ssr snapshot test > ssr test ./src/list/_example/size.vue 1`] = `"
ssr test ./src/list/_example/stripe.vue 1`] = `"
"`; -exports[`ssr snapshot test > ssr test ./src/list/_example/virtual-scroll.vue 1`] = `"
"`; +exports[`ssr snapshot test > ssr test ./src/list/_example/virtual-scroll.vue 1`] = `"
"`; exports[`ssr snapshot test > ssr test ./src/loading/_example/attach.vue 1`] = `"
Hello, I'm Alice. I'm going to be a front-end developer.
隐藏
"`;