虚拟滚动
一个用于在有限空间(行或列)内展示内容的容器组件。与步进滚动器不同,它模拟了浏览器原生的平滑滚动体验(无级滚动),支持自定义滚动条样式或通过长按按钮进行连续滚动。
基础用法
默认情况下,组件使用水平布局并显示一个自定义的滚动条。
vue
<script setup>
import { ref } from 'vue'
const list = ref(Array.from({ length: 20 }, (_, i) => i + 1))
</script>
<template>
<div style="height: 60px;">
<TuiVirtualScroller>
<div v-for="item in list" :key="item" class="item-box">
Item {{ item }}
</div>
</TuiVirtualScroller>
</div>
</template>
<style scoped>
.item-box {
padding: 0 20px;
border: 1px solid var(--tui-border-color);
display: flex;
align-items: center;
border-radius: 4px;
}
</style>控制类型
这是该组件的核心特性。通过 ctrlType 属性,你可以决定用户如何进行滚动操作。
- scrollbar (默认): 显示一个样式化的滚动条,支持拖拽。
- button: 隐藏滚动条,显示两侧的控制按钮。长按按钮可实现平滑的连续滚动。
- none: 隐藏所有可视化控制器,仅支持鼠标滚轮或触摸滑动。
vue
<script setup>
import { reactive } from 'vue'
const config = reactive({
type: 'scrollbar'
})
</script>
<template>
<div class="control-panel">
<TuiRadio v-model="config.type" :options="['scrollbar', 'button', 'none']" />
</div>
<div style="height: 80px; margin-top: 20px;">
<TuiVirtualScroller :ctrlType="config.type">
<div v-for="i in 15" :key="i" class="item">Element {{ i }}</div>
</TuiVirtualScroller>
</div>
</template>按钮模式配置
当 ctrlType="button" 时,你可以进一步定制按钮的行为和外观。
buttonPosition: 控制按钮位置。
both: 两侧各一个 (默认)。start: 都在起始位置。end: 都在结束位置。float: 悬浮在内容上方。buttonSize: 按钮尺寸 (
small,default,large)。scrollSpeed: 控制长按按钮时的滚动速度倍率。
vue
<template>
<TuiVirtualScroller
ctrlType="button"
buttonPosition="float"
buttonSize="large"
:scrollSpeed="2"
>
</TuiVirtualScroller>
</template>滚动条模式配置
当 ctrlType="scrollbar" 时,可以通过 scrollbarSize 控制滚动条的粗细,使其适应不同的 UI 密度。
可选值:mini (极细), small, default, large, xlarge。
vue
<template>
<div style="height: 60px;">
<TuiVirtualScroller ctrlType="scrollbar" scrollbarSize="mini">
<div v-for="i in 10" :key="i" class="item">Mini Scrollbar</div>
</TuiVirtualScroller>
</div>
</template>表单组件适配
与 StepScroller 一样,VirtualScroller 也深度适配了 TuiRadio 和 TuiCheckbox。当选项过多时,使用此组件可以避免占用过多的页面空间。
推荐设置 border="auto" 或 border="none" 以获得最佳视觉效果。
vue
<script setup>
import { ref } from 'vue'
const radioVal = ref(1)
const checkVal = ref([])
</script>
<template>
<div style="height: 50px;">
<TuiVirtualScroller border="auto">
<TuiRadio v-model="radioVal" appearance="button">
<TuiRadioItem v-for="i in 20" :key="i" :value="i">Opt{{ i }}</TuiRadioItem>
</TuiRadio>
</TuiVirtualScroller>
</div>
<div style="height: 50px; margin-top: 20px;">
<TuiVirtualScroller border="none">
<TuiCheckbox v-model="checkVal" appearance="button">
<TuiCheckboxItem v-for="i in 20" :key="i" :value="i">Chk{{ i }}</TuiCheckboxItem>
</TuiCheckbox>
</TuiVirtualScroller>
</div>
</template>垂直方向
设置 direction="v" 即可开启垂直滚动。请务必为父容器设置明确的高度。
vue
<template>
<div style="height: 300px; width: 200px;">
<TuiVirtualScroller direction="v" ctrlType="scrollbar">
<div v-for="i in 20" :key="i" class="v-item">Vertical {{ i }}</div>
</TuiVirtualScroller>
</div>
</template>API 参考
Props
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| direction | 滚动方向,可选 'h', 'v' | String | 'h' |
| ctrlType | 控制器类型,可选 'scrollbar', 'button', 'none' | String | 'scrollbar' |
| border | 边框策略,可选 'auto', 'none', 'always' | String | 'auto' |
| buttonPosition | 按钮位置 (仅 button 模式),可选 'both', 'start', 'end', 'float' | String | 'both' |
| buttonSize | 按钮尺寸 (仅 button 模式),可选 'default', 'small', 'large' | String | 'default' |
| scrollbarSize | 滚动条粗细 (仅 scrollbar 模式),可选 'mini', 'small', 'default', 'large', 'xlarge' | String | 'small' |
| scrollSpeed | 按钮滚动模式下的滚动速度倍率 | Number | 1 |
| resizeObserver | 尺寸监听策略,可选 'self', 'global', 'none' | String | 'self' |
Expose
组件暴露了以下方法,可通过 ref 调用以实现编程式滚动。
| 名称 | 说明 | 类型 |
|---|---|---|
| scrollTo | 滚动到指定像素位置 | (position: number) => void |
| scrollToTop | 滚动到顶部 (或最左侧) | () => void |
| scrollToBottom | 滚动到底部 (或最右侧) | () => void |
| scrollPosition | 获取当前滚动位置 (像素) | number (Ref) |
| maxScroll | 获取最大可滚动距离 | number (Ref) |
Slots
| 插槽名 | 说明 |
|---|---|
| default | 滚动容器内的内容 |