在处理大数据量表格时,性能是首要考虑的问题。vxe-table 提供了强大的虚拟滚动能力,结合滚动事件即可实现"滚动到底部自动加载更多"的无感加载体验,几行代码就能完成。
功能概述
- 虚拟滚动:仅渲染可视区域内的行,大幅减少 DOM 节点数量,支持海量数据流畅滚动。
- 滚动加载:监听滚动事件,触底时自动请求下一页数据并追加到列表中,用户无感知。
- 分页兼容:滚动加载可与分页并存,用户看不到分页按钮,体验上像是无限下拉。
核心配置
启用纵向虚拟滚动
javascript
virtualYConfig: {
enabled: true, // 启用虚拟滚动
gt: 0 // 数据量超过 0 行即启用,设为 0 表示始终启用
}
- enabled:总开关。
- gt:阈值,超过该行数才启用虚拟滚动。设为 0 表示始终启用。
- 需要为表格设置固定高度,虚拟滚动依赖可视区域高度计算渲染范围。
监听滚动事件
javascript
const gridEvents = {
scroll({ isTop, isBottom }) {
if (isBottom) {
loadList(20) // 触底加载更多
}
}
}
- scroll 事件返回 isTop 和 isBottom,用于判断是否滚动到顶部或底部。
- 在 isBottom 为 true 时调用加载函数。
防止重复加载
javscript
const loadList = (size = 200) => {
if (gridOptions.loading) {
return // 加载中则跳过,避免重复请求
}
gridOptions.loading = true
// ... 请求数据
gridOptions.loading = false
}
使用 loading 状态作为锁,确保上一次请求完成后才能触发下一次加载。
代码

html
<template>
<div>
<vxe-grid v-bind="gridOptions" v-on="gridEvents"></vxe-grid>
</div>
</template>
<script setup>
import { reactive } from 'vue'
const gridOptions = reactive({
border: true,
loading: false,
showOverflow: true,
showHeaderOverflow: true,
showFooterOverflow: true,
height: 600,
columnConfig: {
resizable: true
},
virtualYConfig: {
enabled: true,
gt: 0
},
columns: [
{ type: 'seq', width: 80 },
{ field: 'id', title: 'ID', width: 120 },
{ field: 'name', title: 'Name' },
{ field: 'role', title: 'Role' },
{ field: 'sex', title: 'Sex', width: 100 }
],
data: []
})
let rowKey = 0
// 模拟行数据
const loadList = (size = 200) => {
if (gridOptions.loading) {
return
}
// 模拟后端接口
gridOptions.loading = true
setTimeout(() => {
const dataList = []
for (let i = 0; i < size; i++) {
rowKey++
dataList.push({
id: `${rowKey}`,
name: 'Test' + rowKey,
role: 'Developer' + rowKey,
sex: '男'
})
}
gridOptions.data = [...gridOptions.data, ...dataList]
gridOptions.loading = false
}, 300)
}
const gridEvents = {
scroll({ isTop, isBottom }) {
if (isTop) {
console.log('触碰到顶部')
}
if (isBottom) {
console.log('触碰到底部')
loadList(20)
}
}
}
loadList(20)
</script>
关键代码说明
滚动事件与触底加载
javascript
scroll({ isTop, isBottom }) {
if (isBottom) {
loadList(20)
}
}
- isBottom 表示已滚动到距底部一定范围内,是触发加载的时机。
- 也可使用 scroll-boundary 事件,通过 virtualYConfig.threshold 设置阈值,例如距底部 30px 内触发
数据追加与响应式
javascript
gridOptions.data = [...gridOptions.data, ...dataList]
使用展开运算符创建新数组并赋值给 gridOptions.data,确保 Vue 能检测到数据变化并触发更新。
加载状态锁
javascript
if (gridOptions.loading) return
loading 既是 UI 状态,也是防止重复请求的锁。滚动过程中可能频繁触发 scroll 事件,若没有这个判断,会发起多次重复请求。
进阶用法:scroll-boundary 事件
除了 scroll 事件,vxe-table 还提供了 scroll-boundary 事件,通过阈值触发加载,更加精准。
html
<vxe-grid v-bind="gridOptions" @scroll-boundary="scrollBoundaryEvent"></vxe-grid>
javascript
scrollY: {
enabled: true,
gt: 0,
threshold: 30 // 距底部 30px 内触发
}
scrollBoundaryEvent({ direction }) {
if (direction === 'bottom') {
loadList(20)
}
}
- threshold:设置触发阈值,当滚动距离达到该范围内时触发事件。
- direction:返回触发方向,'bottom' 表示触底。
通过 virtualYConfig 启用虚拟滚动,结合 scroll 或 scroll-boundary 事件触底加载,即可用极少的代码实现高性能的滚动加载表格。这种方案特别适合数据量大、需要连续浏览的场景,能显著提升用户体验。