在后台管理系统的数据展示场景中,信息密度与可读性往往是一对矛盾。普通表格行高充裕、视觉舒适,但一屏可见的数据行数有限;紧凑型表格则能在有限空间内展示更多数据,尤其适合大屏监控、批量操作、数据对比等场景。
vxe-table 提供了灵活的单元格尺寸定制能力,允许开发者精确控制行高与内边距,快速构建紧凑型表格。本文将详细讲解其配置方式、性能优化策略以及关键注意事项,帮助您在高密度与用户体验之间取得最佳平衡。
核心配置:cellConfig.height 与 padding
vxe-table 通过 cellConfig 对象控制单元格的尺寸与内边距:
| 属性 | 类型 | 说明 |
|---|---|---|
| cellConfig.height | number | 单元格高度(单位 px),默认值为 22(标准行高) |
| cellConfig.padding.top / bottom | boolean | 是否启用上下内边距,默认为 true(即 10px 左右内边距)。设为 false 可进一步压缩 |
紧凑型配置示例:
javascript
const cellConfig = reactive({
height: 30, // 行高 30px(推荐可编辑表格最小值)
padding: {
top: false, // 移除上内边距
bottom: false // 移下下内边距
}
})
- 尺寸建议(官方推荐):
- 纯展示型列表:单元格高度不低于 22px(默认值),低于该值可能导致布局错乱或文字截断。
- 可编辑表格(含输入框、选择器等控件):单元格高度不低于 30px,确保标准控件(如 VxeInput)能完整显示且可操作。
若设置 height 低于 22px,还需额外调整 CSS 变量 --vxe-ui-table-row-line-height(见后文)。
代码

html
<template>
<div>
<div>
<vxe-button @click="loadList(10000)">加载1万行</vxe-button>
<vxe-button @click="loadList(30000)">加载3万行</vxe-button>
<vxe-button @click="loadList(50000)">加载5万行</vxe-button>
<vxe-button @click="loadList(100000)">加载10万行</vxe-button>
<vxe-button @click="loadList(200000)">加载20万行</vxe-button>
</div>
<div>
高度:<vxe-radio-group v-model="cellConfig.height">
<vxe-radio-button :checked-value="22" content="22px"></vxe-radio-button>
<vxe-radio-button :checked-value="26" content="26px"></vxe-radio-button>
<vxe-radio-button :checked-value="30" content="30px"></vxe-radio-button>
<vxe-radio-button :checked-value="34" content="34px"></vxe-radio-button>
<vxe-radio-button :checked-value="38" content="38px"></vxe-radio-button>
</vxe-radio-group>
</div>
<vxe-grid ref="gridRef" class="my-compact-table" v-bind="gridOptions"></vxe-grid>
</div>
</template>
<script setup>
import { ref, onMounted, reactive } from 'vue'
import { VxeUI } from 'vxe-table'
const gridRef = ref()
const cellConfig = reactive({
padding: {
top: false,
bottom: false
},
height: 30
})
const gridOptions = reactive({
border: true,
loading: false,
showOverflow: true,
size: 'mini',
height: 800,
cellConfig,
mouseConfig: {
area: true, // 是否开启区域选取
extension: false
},
toolbarConfig: {
custom: true
},
keyboardConfig: {
arrowCursorLock: true, // 方向键光标锁,开启后处于非聚焦式编辑状态,将支持在编辑状态中通过方向键切换单元格。(切换为聚焦编辑状态,可以按 F2 键或者鼠标左键点击输入框,就可以用方向键左右移动输入框的光标)
isClip: true, // 是否开启复制粘贴
isArrow: true, // 是否开启方向键功能
isShift: true, // 是否开启同时按住方向键以活动区域为起始,向指定方向扩展单元格区域
isTab: true, // 是否开启 Tab 键功能
isEnter: true, // 是否开启回车键功能
isEsc: true, // 是否开启Esc键关闭编辑功能
isFNR: true // 是否开启查找与替换
},
virtualYConfig: {
enabled: true, // 是否开启纵向虚拟滚动
gt: 0 // 指定大于指定行时自动启动纵向虚拟滚动,如果为 0 则总是启用
},
columns: [
{ type: 'seq', width: 80 },
{ type: 'checkbox', width: 60 },
{ field: 'a', title: 'A', width: 140 },
{ field: 'b', title: 'B', width: 180 },
{ field: 'c', title: 'C', width: 120 },
{ field: 'd', title: 'D', width: 180 },
{ field: 'e', title: 'E', width: 100 },
{ field: 'f', title: 'F', width: 120 },
{ field: 'g', title: 'G', width: 120 },
{ field: 'h', title: 'H', width: 140 },
{ field: 'i', title: 'I', width: 180 },
{ field: 'j', title: 'J', width: 180 },
{ field: 'k', title: 'K', width: 180 },
{ field: 'l', title: 'L', width: 120 },
{ field: 'm', title: 'M', width: 120 },
{ field: 'n', title: 'N', width: 140 },
{ field: 'o', title: 'O', width: 70 },
{ field: 'p', title: 'P', width: 80 },
{ field: 'q', title: 'Q', width: 100 },
{ field: 's', title: 'S', width: 150 },
{ field: 't', title: 'T', width: 120 }
]
})
const loadList = (rowSize = 100, isMsg = true) => {
gridOptions.loading = true
setTimeout(() => {
const $grid = gridRef.value
const list = []
for (let i = 0; i < rowSize; i++) {
list.push({ id: 10001 + i, a: `Test${i}`, b: 'Develop', c: 'Man', d: `${10 + i}`, e: `${(10 + i) % 66}`, f: 'Shengzhen', g: '', h: `h${i}`, i: `i${i}`, j: `j${i}`, k: `k${i}`, l: `l${i}` })
}
if ($grid) {
const startTime = Date.now()
$grid.reloadData(list).then(() => {
if (isMsg) {
VxeUI.modal.message({
content: `加载时间 ${Date.now() - startTime} 毫秒`,
status: 'success'
})
}
gridOptions.loading = false
})
} else {
gridOptions.loading = false
}
}, 200)
}
onMounted(() => {
loadList(200, false)
})
</script>
<style lang="scss" scoped>
// .my-compact-table {
// --vxe-ui-table-row-line-height: 18px; // 当单元格高度低于默认 22px 时,需要同时修改默认行高 css 变量,例如:18px
// }
</style>
关键点
行高与 CSS 变量的联动
当 cellConfig.height 设置值小于默认的 22px 时,仅调整 JS 配置还不够,因为表格内部的行高还受 CSS 变量 --vxe-ui-table-row-line-height 控制。
必须同步修改该变量,否则单元格内容垂直对齐会错位。示例:
css
.my-compact-table {
--vxe-ui-table-row-line-height: 18px; // 与 cellConfig.height 保持一致
}
若行高 ≥ 22px,则无需额外设置,因为默认行高就是 22px,且组件内部会自动适配。
可编辑表格的最低高度
若表格中使用了输入框、下拉框、日期选择器等编辑控件(editRender),建议高度不低于 30px,否则控件显示不全或无法交互。官方推荐的可编辑表格最小高度即为 30px。
性能优化------虚拟滚动必开
紧凑型表格往往用于展示大量数据,virtualYConfig 是保证流畅性的核心。示例中设置了 enabled: true 和 gt: 0,即数据量 >0 时自动启用虚拟滚动,仅渲染可视区域的行,大幅减少 DOM 节点。
列宽与内容溢出
紧凑行高下,单元格宽度若不足,文本可能被截断(showOverflow: true 会显示省略号)。建议合理设置列宽(width 或 minWidth),或通过 ellipsis 配置自定义提示。
交互反馈
紧凑型表格的行高变矮,鼠标点击区域也随之缩小,若开启编辑或选区功能,需确保操作热区足够大。可通过 mouseConfig.area 开启区域选取,并配合键盘操作提升效率。
适用场景与取舍
| 场景 | 推荐行高 | 是否启用 padding | 备注 |
|---|---|---|---|
| 纯展示性列表(监控大屏、数据概览) | 22~26px | 移除(padding: false) | 最大化信息密度 |
| 常规管理列表(带操作按钮、状态标签) | 30~34px | 保留或移除视情况 | 兼顾操作舒适度 |
| 可编辑表格(单元格内嵌输入框) | ≥30px | 保留(确保控件可交互) | 不可低于 30px |
| 复杂表格(含多行文本、换行) | 自适应(showOverflow: false) | 按需 | 此时不使用紧凑型 |
动态切换行高
通过将 cellConfig.height 绑定为响应式变量,并配合单选按钮组,用户可随时切换行高,适应不同场景。vxe-table 会自动检测配置变化并重新渲染,无需额外代码。
vxe-table 通过 cellConfig.height 和 padding 提供了精细的行高控制能力,让开发者能够轻松构建紧凑型表格,在有限空间内展示更多数据。配合虚拟滚动和合理的最小高度建议,即可实现高密度、高性能、可交互的表格方案。
实际项目中,建议根据业务场景选择合适的行高,并在用户界面提供切换入口,兼顾不同用户的使用习惯。