【Element Plus】虚拟化表格动态渲染大量数据

540 阅读2分钟

最近有个需求是用表格渲染大量数据,寻常使用用el-table渲染时,发现浏览器崩溃了눈_눈 。需要有效的解决方案来确保应用的流畅性,在这里记录一下Virtualized Table虚拟化表格动态渲染大量数据的用法。

Element Plus 官网中的虚拟化表格UI比较丑,我们需要改一下,跟el-table基本保持。

​编辑

实现步骤

  • 渲染表格

在模板部分,我们使用 el-table-v2 组件来渲染表格,并通过插槽自定义单元格内容。其中header-cell插槽可自定义表头,一行显示,超出显示...,鼠标悬停显示tooltip。cell插槽渲染行数据与此类似(也许出于性能考虑,el-table-v2鼠标悬停显示的是原生:title的形式)。需要注意的是,虚拟化表格的宽高是必传的,且是数字的类型。

<el-table-v2 border :data="tableData" :columns="tableColumns" :width="tableWidth" :height="tableHeight" fixed>
  <template #header-cell="{ column }">
    <el-tooltip effect="dark" :content="column.title" placement="top" raw-content>
      <span class="line-clamp-1 break-all">{{ column.title }}</span>
    </el-tooltip>
  </template>
  <template #cell="{ column, rowData }">
    <el-tooltip
      effect="dark"
      :content="rowData[column.dataKey]"
      placement="top"
      raw-content
      v-if="rowData[column.dataKey]"
    >
      <span class="line-clamp-1 break-all">{{ rowData[column.dataKey] }}</span>
    </el-tooltip>
  </template>
</el-table-v2>

  • 引入TypeScript类型

import type { Column } from 'element-plus'

  • 设置表格数据和列

通过 API 请求获取数据,并动态生成表格列。

const tableData = ref<Record<string, any>[]>([])
const tableColumns = computed<Column[]>(() => {
  if (!getDataPageApi.response?.data?.fieldList) return []
  let obj = getDataPageApi.response?.data?.fieldList[0]
  let list = []
  list.push({
    dataKey: IndexKey.key,
    key: IndexKey.key,
    title: IndexKey.label,
    width: 100,
    fixed: true,
  })
  for (const key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      list.push({
        dataKey: key,
        key: key,
        title: key,
        width: 200,
      })
    }
  }
  return list
})

  • 计算表格宽高

根据窗口大小动态设置表格的宽高,并监听窗口变化以调整布局。

const tableWidth = ref(0)
const tableHeight = computed(() => {
  const headerH = 50
  const rowH = 50
  if (tableData.value.length < 10) {
    return headerH + rowH * tableData.value.length
  } else {
    return rowH * 10 + headerH
  }
})

const onTableWidthChange = () => {
  const table = document.getElementById('myTable')
  tableWidth.value = table?.offsetWidth! || 0
}

window.addEventListener('resize', onTableWidthChange)

  • 样式定制

我们通过 scoped 样式自定义表格的外观,确保其在各种屏幕尺寸上都能良好显示。

<style lang="less" scoped>
:deep(.el-table-v2__header-cell) {
  flex: 1 !important;
  background-color: #e7e7e7;
  color: #00000088;
  box-shadow: -1px 0 0 0 #ebeef5 inset; /* 仅在右边显示阴影 */
  &:last-child {
    box-shadow: none;
  }
}
:deep(.el-table-v2__row-cell) {
  flex: 1 !important;
  box-shadow: -1px 0 0 0 #ebeef5 inset; /* 仅在右边显示阴影 */
  &:last-child {
    box-shadow: none;
  }
}
</style>

实现效果

总体效果

​编辑

表头超出显示省略号

​编辑

以上就是虚拟化表格动态渲染大量数据的实现啦^-^