vxe-table 紧凑型表格:在高密度数据与可读性之间找到平衡

在后台管理系统的数据展示场景中,信息密度与可读性往往是一对矛盾。普通表格行高充裕、视觉舒适,但一屏可见的数据行数有限;紧凑型表格则能在有限空间内展示更多数据,尤其适合大屏监控、批量操作、数据对比等场景。
vxe-table 提供了灵活的单元格尺寸定制能力,允许开发者精确控制行高与内边距,快速构建紧凑型表格。本文将详细讲解其配置方式、性能优化策略以及关键注意事项,帮助您在高密度与用户体验之间取得最佳平衡。

核心配置:cellConfig.height 与 padding

vxe-table 通过 cellConfig 对象控制单元格的尺寸与内边距:

属性 类型 说明
cellConfig.height number 单元格高度(单位 px),默认值为 22(标准行高)
cellConfig.padding.top / bottom boolean 是否启用上下内边距,默认为 true(即 10px 左右内边距)。设为 false 可进一步压缩

紧凑型配置示例:

const cellConfig = reactive({
  height: 30,                // 行高 30px(推荐可编辑表格最小值)
  padding: {
    top: false,              // 移除上内边距
    bottom: false            // 移下下内边距
  }
})
  • 尺寸建议(官方推荐):
    • 纯展示型列表:单元格高度不低于 22px(默认值),低于该值可能导致布局错乱或文字截断。
    • 可编辑表格(含输入框、选择器等控件):单元格高度不低于 30px,确保标准控件(如 VxeInput)能完整显示且可操作。

若设置 height 低于 22px,还需额外调整 CSS 变量 --vxe-ui-table-row-line-height(见后文)。

代码

Video_2026-08-20_135327-ezgif.com-video-to-gif-converter (1)

<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 控制。
必须同步修改该变量,否则单元格内容垂直对齐会错位。示例:

.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 提供了精细的行高控制能力,让开发者能够轻松构建紧凑型表格,在有限空间内展示更多数据。配合虚拟滚动和合理的最小高度建议,即可实现高密度、高性能、可交互的表格方案。
实际项目中,建议根据业务场景选择合适的行高,并在用户界面提供切换入口,兼顾不同用户的使用习惯。

https://vxetable.cn

posted @ 2026-08-26 13:41  你个老六  阅读(2)  评论(0)    收藏  举报