Appearance
Table 表格
Table 组件用于展示结构化数据,默认支持分页。当 total > 0 时会自动显示分页;也可以通过传入 showPagination 强制显示分页。
基础用法
显式开启分页(
total=0时仍显示):ID 姓名 年龄 地址 1 张伟 22 北京市朝阳区中关村大街1号 2 李秀英静 23 上海市海淀区建国门外大街1号 3 王丽 24 广州市西城区王府井大街1号 4 刘军涛 25 深圳市东城区西单北大街1号 5 陈艳 26 杭州市丰台区东单北大街1号 6 杨涛华 27 成都市石景山区复兴路1号 7 赵秀兰 28 武汉市通州区长安街1号 8 黄刚桂芬 29 西安市昌平区三环路1号 9 周文 30 南京市大兴区四环路1号 10 吴红静 31 重庆市房山区五环路1号 总条数自定义分页文案与页大小:
ID 姓名 年龄 地址 1 张伟 22 北京市朝阳区中关村大街1号 2 李秀英静 23 上海市海淀区建国门外大街1号 3 王丽 24 广州市西城区王府井大街1号 4 刘军涛 25 深圳市东城区西单北大街1号 5 陈艳 26 杭州市丰台区东单北大街1号 6 杨涛华 27 成都市石景山区复兴路1号 7 赵秀兰 28 武汉市通州区长安街1号 8 黄刚桂芬 29 西安市昌平区三环路1号 9 周文 30 南京市大兴区四环路1号 10 吴红静 31 重庆市房山区五环路1号 共 35 条空数据与占位文案:
ID 姓名 年龄 地址 暂无数据自定义列宽与对齐:
ID 姓名 分数 1 张伟 94 2 李秀英静 63 3 王丽 84 4 刘军涛 70 5 陈艳 71 6 杨涛华 80 7 赵秀兰 85 8 黄刚桂芬 60 总条数使用
rowKey:唯一键 姓名 row-1763545355052-0 张伟 row-1763545355052-1 李秀英静 row-1763545355052-2 王丽 row-1763545355052-3 刘军涛 row-1763545355052-4 陈艳 总条数不同尺寸:
ID 姓名 1 张伟 2 李秀英静 3 王丽 4 刘军涛 5 陈艳 6 杨涛华 总条数ID 姓名 1 张伟 2 李秀英静 3 王丽 4 刘军涛 5 陈艳 6 杨涛华 总条数ID 姓名 1 张伟 2 李秀英静 3 王丽 4 刘军涛 5 陈艳 6 杨涛华 总条数列宽拖拽:
ID 姓名 年龄 地址 ID 姓名 年龄 地址 1 张伟 22 北京市朝阳区中关村大街1号 1 张伟 22 北京市朝阳区中关村大街1号 2 李秀英静 23 上海市海淀区建国门外大街1号 2 李秀英静 23 上海市海淀区建国门外大街1号 3 王丽 24 广州市西城区王府井大街1号 3 王丽 24 广州市西城区王府井大街1号 4 刘军涛 25 深圳市东城区西单北大街1号 4 刘军涛 25 深圳市东城区西单北大街1号 5 陈艳 26 杭州市丰台区东单北大街1号 5 陈艳 26 杭州市丰台区东单北大街1号 6 杨涛华 27 成都市石景山区复兴路1号 6 杨涛华 27 成都市石景山区复兴路1号 7 赵秀兰 28 武汉市通州区长安街1号 7 赵秀兰 28 武汉市通州区长安街1号 8 黄刚桂芬 29 西安市昌平区三环路1号 8 黄刚桂芬 29 西安市昌平区三环路1号 9 周文 30 南京市大兴区四环路1号 9 周文 30 南京市大兴区四环路1号 10 吴红静 31 重庆市房山区五环路1号 10 吴红静 31 重庆市房山区五环路1号 总条数提示:将鼠标移动到表头最右侧,即可拖拽调整列宽。
自定义单元格插槽(操作列):
ID 姓名 年龄 操作 1 张伟 22 2 李秀英静 23 3 王丽 24 4 刘军涛 25 5 陈艳 26 6 杨涛华 27 7 赵秀兰 28 8 黄刚桂芬 29 9 周文 30 10 吴红静 31 总条数使用子组件定义列(Element Plus 风格):
总条数事件用法示例(监听
pageChange):ID 姓名 年龄 地址 1 张伟 22 北京市朝阳区中关村大街1号 2 李秀英静 23 上海市海淀区建国门外大街1号 3 王丽 24 广州市西城区王府井大街1号 4 刘军涛 25 深圳市东城区西单北大街1号 5 陈艳 26 杭州市丰台区东单北大街1号 6 杨涛华 27 成都市石景山区复兴路1号 7 赵秀兰 28 武汉市通州区长安街1号 8 黄刚桂芬 29 西安市昌平区三环路1号 9 周文 30 南京市大兴区四环路1号 10 吴红静 31 重庆市房山区五环路1号 总条数服务端分页(模拟请求):
ID 姓名 年龄 地址 暂无数据总条数动态列显示/隐藏:
ID 姓名 年龄 地址 ID 姓名 年龄 地址 1 张伟 22 北京市朝阳区中关村大街1号 1 张伟 22 北京市朝阳区中关村大街1号 2 李秀英静 23 上海市海淀区建国门外大街1号 2 李秀英静 23 上海市海淀区建国门外大街1号 3 王丽 24 广州市西城区王府井大街1号 3 王丽 24 广州市西城区王府井大街1号 4 刘军涛 25 深圳市东城区西单北大街1号 4 刘军涛 25 深圳市东城区西单北大街1号 5 陈艳 26 杭州市丰台区东单北大街1号 5 陈艳 26 杭州市丰台区东单北大街1号 6 杨涛华 27 成都市石景山区复兴路1号 6 杨涛华 27 成都市石景山区复兴路1号 7 赵秀兰 28 武汉市通州区长安街1号 7 赵秀兰 28 武汉市通州区长安街1号 8 黄刚桂芬 29 西安市昌平区三环路1号 8 黄刚桂芬 29 西安市昌平区三环路1号 9 周文 30 南京市大兴区四环路1号 9 周文 30 南京市大兴区四环路1号 10 吴红静 31 重庆市房山区五环路1号 10 吴红静 31 重庆市房山区五环路1号 总条数固定表头与横向滚动:
ID 姓名 部门 职位 邮箱 地址 1 张伟 技术部 前端工程师 user00@example.com 北京市朝阳区中关村大街1号 2 李秀英静 产品部 后端工程师 user11@example.com 上海市海淀区建国门外大街1号 3 王丽 设计部 产品经理 user22@example.com 广州市西城区王府井大街1号 4 刘军涛 运营部 UI设计师 user33@example.com 深圳市东城区西单北大街1号 5 陈艳 市场部 运营专员 user44@example.com 杭州市丰台区东单北大街1号 6 杨涛华 财务部 市场专员 user55@example.com 成都市石景山区复兴路1号 7 赵秀兰 人事部 财务专员 user66@example.com 武汉市通州区长安街1号 8 黄刚桂芬 行政部 人事专员 user77@example.com 西安市昌平区三环路1号 9 周文 技术部 前端工程师 user88@example.com 南京市大兴区四环路1号 10 吴红静 产品部 后端工程师 user99@example.com 重庆市房山区五环路1号 总条数横向滚动(内置属性
scrollX):ID 姓名 部门 职位 邮箱 地址 城市 省份 邮编 1 张伟 技术部 前端工程师 user00@example.com 北京市朝阳区中关村大街1号 北京市 北京市 100000 2 李秀英静 产品部 后端工程师 user11@example.com 上海市海淀区建国门外大街1号 上海市 上海市 100001 3 王丽 设计部 产品经理 user22@example.com 广州市西城区王府井大街1号 广州市 广东省 100002 4 刘军涛 运营部 UI设计师 user33@example.com 深圳市东城区西单北大街1号 深圳市 浙江省 100003 5 陈艳 市场部 运营专员 user44@example.com 杭州市丰台区东单北大街1号 杭州市 江苏省 100004 6 杨涛华 财务部 市场专员 user55@example.com 成都市石景山区复兴路1号 成都市 四川省 100005 7 赵秀兰 人事部 财务专员 user66@example.com 武汉市通州区长安街1号 武汉市 湖北省 100006 8 黄刚桂芬 行政部 人事专员 user77@example.com 西安市昌平区三环路1号 西安市 陕西省 100007 9 周文 技术部 前端工程师 user88@example.com 南京市大兴区四环路1号 南京市 河南省 100008 10 吴红静 产品部 后端工程师 user99@example.com 重庆市房山区五环路1号 重庆市 山东省 100009 总条数
基础用法代码示例
vue
<script setup lang="ts">
import { ref } from 'vue'
const columns = [
{ key: 'id', title: 'ID', width: 80 },
{ key: 'name', title: '名称' },
{ key: 'age', title: '年龄', align: 'center', width: 100 },
{ key: 'address', title: '地址' }
]
// 模拟数据生成辅助函数
const surnames = ['张', '李', '王', '刘', '陈', '杨', '赵', '黄', '周', '吴']
const givenNames = ['伟', '芳', '娜', '敏', '静', '丽', '强', '磊', '军', '洋']
const cities = [
'北京市',
'上海市',
'广州市',
'深圳市',
'杭州市',
'成都市',
'武汉市',
'西安市',
'南京市',
'重庆市'
]
const districts = ['朝阳区', '海淀区', '西城区', '东城区', '丰台区']
const streets = [
'中关村大街',
'建国门外大街',
'王府井大街',
'西单北大街',
'东单北大街'
]
function generateName(index: number) {
const surname = surnames[index % surnames.length]
const givenName =
givenNames[(index * 3) % givenNames.length] +
(index % 2 === 0 ? '' : givenNames[(index * 5) % givenNames.length])
return surname + givenName
}
function generateAddress(index: number) {
const city = cities[index % cities.length]
const district = districts[index % districts.length]
const street = streets[index % streets.length]
const number = Math.floor(index / 10) + 1
return `${city}${district}${street}${number}号`
}
const data = Array.from({ length: 35 }).map((_, i) => ({
id: i + 1,
name: generateName(i),
age: 22 + (i % 24),
address: generateAddress(i)
}))
const currentPage = ref(1)
const pageSize = ref(10)
</script>
<template>
<c-table
:columns="columns"
:data="data"
:total="data.length"
v-model:currentPage="currentPage"
v-model:pageSize="pageSize"
/>
</template>自定义列宽与对齐
通过在 columns 中设置 width 与 align 可控制列的宽度与文字对齐方式。
vue
<script setup lang="ts">
const alignColumns = [
{ key: 'id', title: 'ID', width: 80, align: 'center' },
{ key: 'name', title: '名称', width: 160 },
{ key: 'score', title: '分数', align: 'right', width: 100 }
]
const alignData = Array.from({ length: 8 }).map((_, i) => ({
id: i + 1,
name: generateName(i),
score: Math.round(60 + Math.random() * 40)
}))
</script>
<template>
<c-table
:columns="alignColumns"
:data="alignData"
:total="alignData.length"
/>
<!-- 可强制显示分页(示例:total 为 0 但仍显示) -->
<c-table
:columns="alignColumns"
:data="alignData"
:total="0"
:show-pagination="true"
/>
<!-- 仅设置列宽,不设置分页 -->
<c-table :columns="alignColumns" :data="alignData" :total="0" />
</template>使用 rowKey
当数据项不使用默认的 id 字段作为唯一标识时,可通过 rowKey 指定唯一键字段,提升列表渲染稳定性。
vue
<script setup lang="ts">
const uuidColumns = [
{ key: 'uuid', title: '唯一键', width: 220 },
{ key: 'name', title: '名称' }
]
const uuidData = Array.from({ length: 5 }).map((_, i) => ({
uuid: `row-${Date.now()}-${i}`,
name: generateName(i)
}))
</script>
<template>
<c-table
:columns="uuidColumns"
:data="uuidData"
:total="uuidData.length"
row-key="uuid"
/>
</template>不同尺寸
通过 size 控制表格的整体视觉密度,提供 small | medium | large 三种尺寸。
vue
<script setup lang="ts">
const sizeColumns = [
{ key: 'id', title: 'ID', width: 80 },
{ key: 'name', title: '名称' }
]
const sizeData = Array.from({ length: 6 }).map((_, i) => ({
id: i + 1,
name: generateName(i)
}))
</script>
<template>
<div class="table-size-demo">
<c-table
size="small"
:columns="sizeColumns"
:data="sizeData"
:total="sizeData.length"
/>
<c-table
size="medium"
:columns="sizeColumns"
:data="sizeData"
:total="sizeData.length"
/>
<c-table
size="large"
:columns="sizeColumns"
:data="sizeData"
:total="sizeData.length"
/>
</div>
</template>
<style>
.table-size-demo .c-table + .c-table {
margin-top: 16px;
}
</style>列宽拖拽
通过为组件传入 columnResizable 开启列宽拖拽,支持通过 minColumnWidth 与 maxColumnWidth 限制拖拽范围(单位:px)。当前版本仅支持像素宽度的列拖拽(不支持百分比宽度)。
vue
<script setup lang="ts">
const dragColumns = [
{ key: 'id', title: 'ID', align: 'center' },
{ key: 'name', title: '名称' },
{ key: 'age', title: '年龄', align: 'center' },
{ key: 'address', title: '地址' },
{ key: 'id', title: 'ID', align: 'center' },
{ key: 'name', title: '名称' },
{ key: 'age', title: '年龄', align: 'center' },
{ key: 'address', title: '地址' },
{ key: 'id', title: 'ID', align: 'center' },
{ key: 'name', title: '名称' },
{ key: 'age', title: '年龄', align: 'center' },
{ key: 'address', title: '地址' }
]
const dragData = Array.from({ length: 12 }).map((_, i) => ({
id: i + 1,
name: generateName(i),
age: 22 + (i % 24),
address: generateAddress(i)
}))
</script>
<template>
<c-table
:columns="dragColumns"
:data="dragData"
:total="dragData.length"
column-resizable
:min-column-width="80"
:max-column-width="500"
/>
<p class="tip">提示:将鼠标移动到表头最右侧,即可拖拽调整列宽。</p>
</template>自定义单元格插槽(操作列)
每列会自动以其 key 作为插槽名称。可通过具名插槽自定义单元格内容,例如添加操作按钮或富文本内容。
vue
<script setup lang="ts">
import { ref } from 'vue'
const actionColumns = [
{ key: 'id', title: 'ID', width: 80, align: 'center' },
{ key: 'name', title: '名称' },
{ key: 'age', title: '年龄', width: 100, align: 'center' },
{ key: 'actions', title: '操作', width: 220, align: 'center' }
]
const actionData = ref(Array.from({ length: 12 }).map((_, i) => ({
id: i + 1,
name: generateName(i),
age: 22 + (i % 24),
actions: ''
})))
function onView(row: any) {
console.log('查看:', row)
}
function onEdit(row: any) {
console.log('编辑:', row)
}
function onDelete(row: any) {
console.log('删除:', row)
actionData.value = actionData.value.filter(r => r.id !== row.id)
}
</script>
<template>
<div class="table-demo">
<c-table
:columns="actionColumns"
:data="actionData"
:total="actionData.length"
:page-sizes="[5, 10, 20]"
v-model:currentPage="currentPage"
v-model:pageSize="pageSize"
>
<!-- 自定义名称列:加粗显示 -->
<template #name="{ row }">
<strong>{{ row.name }}</strong>
</template>
<!-- 自定义操作列:按钮组 -->
<template #actions="{ row }">
<c-button size="small" type="primary" class="action-btn" @click="onView(row)">查看</c-button>
<c-button size="small" type="warning" class="action-btn" @click="onEdit(row)">编辑</c-button>
<c-button size="small" type="danger" plain class="action-btn" @click="onDelete(row)">删除</c-button>
</template>
</c-table>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const currentPage = ref(1)
const pageSize = ref(10)
</script>
<style>
.table-demo .action-btn + .action-btn {
margin-left: 8px;
}
</style>Props
| 属性名 | 说明 | 类型 | 可选值 | 默认值 |
|---|---|---|---|---|
| columns | 列定义 | Array<{ key: string; title: string; width?: number; align?: 'left' | 'center' | 'right' }> | align: left / center / right | — |
| data | 表格数据 | Array<Record<string, any>> | — | — |
| total | 数据总条数,用于分页显示与计算 | number | — | — |
| currentPage | 当前页(支持 v-model:currentPage) | number | — | — |
| pageSize | 每页数量(支持 v-model:pageSize) | number | — | — |
| showPagination | 是否显示分页(即使 total 为 0) | boolean | — | false |
| pageSizes | 可选页大小列表 | number[] | — | — |
| showSizeChanger | 是否显示页大小切换器 | boolean | — | — |
| showTotal | 是否显示总条数文案 | boolean | — | — |
| totalText | 总条数字符串模板,支持 {total} 占位符 | string | — | — |
| emptyText | 空数据占位文案 | string | — | — |
| rowKey | 行唯一键(用于提升渲染效率) | string | — | — |
| size | 表格尺寸 | 'small' | 'medium' | 'large' | small / medium / large | medium |
| columnResizable | 是否开启列宽拖拽 | boolean | — | false |
| minColumnWidth | 最小列宽(px) | number | — | 60 |
| maxColumnWidth | 最大列宽(px) | number | — | 600 |
| scrollX | 是否启用横向滚动。开启后内部表格 min-width 等于所有列宽总和,可出现横向滚动条。 | boolean | — | true |
| height | 表格可视高度。超过该高度时仅内容区(tbody)滚动,表头默认固定。 | number | string | — | 300px |
| stickyHeader | 是否固定表头。固定后,垂直滚动仅发生在内容区,表头保持不动。 | boolean | — | true |
Emits
update:currentPage当前页变更update:pageSize页大小变更pageChange分页变化(包含当前页与页大小)
事件用法示例
在表格上监听 pageChange(或 update:currentPage / update:pageSize)以处理分页变化。
vue
<script setup lang="ts">
import { ref } from 'vue'
const columns = [
{ key: 'id', title: 'ID', width: 80, align: 'center' },
{ key: 'name', title: '名称' },
{ key: 'age', title: '年龄', width: 100, align: 'center' }
]
const allData = Array.from({ length: 50 }).map((_, i) => ({
id: i + 1,
name: generateName(i),
age: 22 + (i % 24)
}))
const currentPage = ref(1)
const pageSize = ref(10)
function onPageChange(page: number, size: number) {
console.log('分页变化', { page, size })
}
</script>
<template>
<c-table
:columns="columns"
:data="allData"
:total="allData.length"
v-model:currentPage="currentPage"
v-model:pageSize="pageSize"
@pageChange="onPageChange"
/>
<!-- 等价:
<c-table
...
@update:currentPage="(p)=>currentPage=p"
@update:pageSize="(s)=>pageSize=s"
/>
-->
</template>服务端分页(示例)
通过监听 pageChange,请求服务端接口加载当前页数据,并更新 data 与 total。
vue
<script setup lang="ts">
import { ref } from 'vue'
const columns = [
{ key: 'id', title: 'ID', width: 80, align: 'center' },
{ key: 'name', title: '名称' },
{ key: 'age', title: '年龄', width: 100, align: 'center' }
]
const data = ref<any[]>([])
const total = ref(0)
const currentPage = ref(1)
const pageSize = ref(10)
async function fetchList(page: number, size: number) {
// 示例:模拟请求,可替换为真实接口
await new Promise((r) => setTimeout(r, 300))
const mockTotal = 123
const start = (page - 1) * size
const pageData = Array.from({ length: size }).map((_, i) => ({
id: start + i + 1,
name: generateName(start + i),
age: 22 + ((start + i) % 24),
address: generateAddress(start + i)
}))
data.value = pageData
total.value = mockTotal
}
function onPageChange(page: number, size: number) {
fetchList(page, size)
}
// 初始化加载
fetchList(currentPage.value, pageSize.value)
</script>
<template>
<c-table
:columns="columns"
:data="data"
:total="total"
v-model:currentPage="currentPage"
v-model:pageSize="pageSize"
@pageChange="onPageChange"
:show-pagination="true"
/>
</template>最佳实践
- 设置
rowKey,确保每行有稳定唯一键,提升渲染稳定性。 - 需要列宽拖拽时,为列设置像素宽度(如
80或"120px")。 - 大量自定义插槽时,尽量减少复杂计算或频繁状态更新,避免性能问题。
- 分页与数据请求分离:通过
pageChange驱动请求,响应后更新data与total。
常见问题
- 为什么列宽拖拽不生效?拖拽仅支持像素宽度,百分比或自适应宽度无法拖拽。
total为 0 时分页不显示?可以通过showPagination强制显示。- 列对齐不生效?检查列定义中的
align是否设置为left|center|right。
动态列显示/隐藏
通过维护可见列的 key 列表,动态计算传入的 columns。
vue
<script setup lang="ts">
import { ref, computed } from 'vue'
const baseColumns = [
{ key: 'id', title: 'ID', width: 80, align: 'center' },
{ key: 'name', title: '名称', width: 160 },
{ key: 'age', title: '年龄', width: 100, align: 'center' },
{ key: 'address', title: '地址', width: 240 }
]
const visibleKeys = ref<string[]>(baseColumns.map((c) => c.key))
const columnsDyn = computed(() =>
baseColumns.filter((c) => visibleKeys.value.includes(c.key))
)
function onToggle(key: string, checked: boolean) {
const set = new Set(visibleKeys.value)
if (checked) set.add(key)
else set.delete(key)
visibleKeys.value = Array.from(set)
}
const dataDyn = Array.from({ length: 12 }).map((_, i) => ({
id: i + 1,
name: generateName(i),
age: 22 + (i % 24),
address: generateAddress(i)
}))
</script>
<template>
<div class="table-dynamic">
<div class="controls">
<label v-for="c in baseColumns" :key="c.key">
<input
type="checkbox"
:checked="visibleKeys.includes(c.key)"
@change="onToggle(c.key, ($event.target as HTMLInputElement).checked)"
/>
{{ c.title }}
</label>
</div>
<c-table :columns="columnsDyn" :data="dataDyn" :total="dataDyn.length" />
</div>
</template>
<style>
.table-dynamic .controls {
margin-bottom: 8px;
}
.table-dynamic .controls label {
margin-right: 12px;
}
</style>固定表头与横向滚动
使用容器滚动,结合 position: sticky 固定表头。横向滚动通过设置较宽的列总宽度触发。
vue
<script setup lang="ts">
const wideColumns = [
{ key: 'id', title: 'ID', width: 100, align: 'center' },
{ key: 'name', title: '名称', width: 240 },
{ key: 'dept', title: '部门', width: 240 },
{ key: 'role', title: '角色', width: 240 },
{ key: 'email', title: '邮箱', width: 300 },
{ key: 'address', title: '地址', width: 360 }
]
const departments = [
'技术部',
'产品部',
'设计部',
'运营部',
'市场部',
'财务部',
'人事部',
'行政部'
]
const roles = [
'前端工程师',
'后端工程师',
'产品经理',
'UI设计师',
'运营专员',
'市场专员',
'财务专员',
'人事专员'
]
function generateEmail(name: string, index: number) {
const pinyin = name.toLowerCase().replace(/[^a-z]/g, '') || `user${index}`
return `${pinyin}${index}@example.com`
}
const wideData = Array.from({ length: 30 }).map((_, i) => {
const name = generateName(i)
return {
id: i + 1,
name,
dept: departments[i % departments.length],
role: roles[i % roles.length],
email: generateEmail(name, i),
address: generateAddress(i)
}
})
// 内置横向滚动示例:列更多、总宽更大
const wideColumns2 = [
{ key: 'id', title: 'ID', width: 100, align: 'center' },
{ key: 'name', title: '名称', width: 240 },
{ key: 'dept', title: '部门', width: 240 },
{ key: 'role', title: '角色', width: 240 },
{ key: 'email', title: '邮箱', width: 300 },
{ key: 'address', title: '地址', width: 360 },
{ key: 'city', title: '城市', width: 240 },
{ key: 'country', title: '国家', width: 240 },
{ key: 'zip', title: '邮编', width: 200 }
]
const provinces = [
'北京市',
'上海市',
'广东省',
'浙江省',
'江苏省',
'四川省',
'湖北省',
'陕西省',
'河南省',
'山东省'
]
const wideData2 = Array.from({ length: 30 }).map((_, i) => {
const name = generateName(i)
const city = cities[i % cities.length]
return {
id: i + 1,
name,
dept: departments[i % departments.length],
role: roles[i % roles.length],
email: generateEmail(name, i),
address: generateAddress(i),
city,
province: provinces[i % provinces.length],
zip: `${100000 + (i % 10000)}`
}
})
</script>
<template>
<div class="table-sticky-scroll">
<c-table :columns="wideColumns" :data="wideData" :total="wideData.length" />
</div>
</template>
<style>
.table-sticky-scroll {
max-height: 220px;
overflow: auto;
border: 1px solid #ebeef5;
}
.table-sticky-scroll .c-table__inner {
min-width: 1200px;
}
.table-sticky-scroll thead .c-table__th {
position: sticky;
top: 0;
z-index: 1;
background: #f8f9fb;
}
</style>类型参考与大数据量建议
ts
// TableColumn 类型(简要)
interface TableColumn {
key: string
title: string
width?: number | string
align?: 'left' | 'center' | 'right'
render?: (row: any, index: number) => any
}- 大数据量建议:
- 使用分页控制每页数据量,避免一次性渲染过多行。
- 对列宽进行合理约束,结合横向滚动避免内容拥挤。
- 如需展示 500+ 行,建议采用虚拟列表技术(目前组件未内置,可自行集成)。