虚拟滚动
当数据选项数量较多时(如上千条),二级面板内置虚拟滚动机制,只渲染视口内可见的选项节点,保证滚动流畅不卡顿。
虚拟滚动对 radio(单选)、checkbox(多选)、map(标签)三种类型的二级面板均生效,无需额外配置。配合 panel-max-height 可控制下拉面板的滚动区域高度。
<template>
<ClientOnly>
<tiny-search-box
v-model="tags"
:items="items"
panel-max-height="300px"
/>
</ClientOnly>
</template>
<script setup lang="ts">
import { ref } from "vue";
import { virtualScrollDataSource } from "./virtual-scroll-data";
const items = virtualScrollDataSource;
const tags = ref([]);
</script>工作原理
- 固定行高(32px),通过滚动监听计算当前可视区域
- 只渲染视口内 + 上下各 5 行缓冲项,DOM 节点数恒定(约 20~30 个)
- 使用占位元素撑开总高度,内容容器通过
translateY定位到正确位置 - 搜索输入变化时自动重置滚动位置到顶部
Data Source
ts
// 生成大数据量数据源,用于演示二级面板数据选项的虚拟滚动效果
// 生成 1000 个单选选项
function generateRadioOptions(count: number) {
return Array.from({ length: count }, (_, i) => ({
label: `选项-${String(i + 1).padStart(4, '0')}`,
id: `radio-${i + 1}`
}))
}
// 生成 500 个多选选项
function generateCheckboxOptions(count: number) {
return Array.from({ length: count }, (_, i) => ({
label: `区域-${String(i + 1).padStart(4, '0')}`,
id: `region-${i + 1}`
}))
}
// 生成 200 个标签(map)选项,每个含 20 个子值
function generateMapOptions(groupCount: number, childCount: number) {
return Array.from({ length: groupCount }, (_, i) => ({
label: `标签组-${String(i + 1).padStart(3, '0')}`,
id: `tag-group-${i + 1}`,
options: Array.from({ length: childCount }, (_, j) => ({
label: `值-${i + 1}-${j + 1}`,
id: `tag-value-${i + 1}-${j + 1}`
}))
}))
}
export const virtualScrollDataSource = [
{
label: '单选项(1000条)',
field: 'radioLarge',
replace: true,
options: generateRadioOptions(1000)
},
{
label: '多选项(500条)',
field: 'checkboxLarge',
type: 'checkbox',
options: generateCheckboxOptions(500)
},
{
label: '标签(200组x20值)',
field: 'mapLarge',
type: 'map',
searchKeys: ['label', 'id'],
options: generateMapOptions(200, 20)
}
]