<template>
<div class="demo-group">
<div class="demo-title">固定表头 + 基础横向滚动</div>
<TsTable fixedHeader :maxHeight="220" :autoFit="false" :columns="longColumns" :dataSource="longDataSource" singleLine>
<template #deliveryAreas="{ row }">
<div class="tag-wrap">
<TsTag v-for="(item, index) in row.deliveryAreas" :key="index">{{ item }}</TsTag>
</div>
</template>
<template #expand="{ closeExpand }">
<div class="docs-table-expand-wrap ts-select-none">
<div class="docs-table-expand-item" @click="closeExpand?.()">查看</div>
<div class="docs-table-expand-item" @click="closeExpand?.()">预览</div>
</div>
</template>
</TsTable>
</div>
<div class="demo-group">
<div class="demo-title">大数据 + 固定列 + 虚拟滚动(750 行)</div>
<div class="demo-tip">
推荐配置:
<code>fixedHeader + maxHeight + singleLine + virtualScroll</code>
,并为大部分列设置
<code>width</code>
。
</div>
<TsTable fixedHeader virtualScroll :virtualRowHeight="40" :virtualOverscan="8" :maxHeight="220" :autoFit="false" :columns="fixedColumns" :dataSource="longDataSSource" singleLine>
<template #deliveryAreas="{ row }">
<div class="tag-wrap">
<TsTag v-for="(item, index) in row.deliveryAreas" :key="index">{{ item }}</TsTag>
</div>
</template>
<template #expand="{ closeExpand }">
<div class="docs-table-expand-wrap ts-select-none">
<div class="docs-table-expand-item" @click="closeExpand?.()">编辑</div>
<div class="docs-table-expand-item" @click="closeExpand?.()">删除</div>
</div>
</template>
<template #actions="{ row }">
<span class="actions-text">详情 · {{ row.productCode }}</span>
</template>
</TsTable>
</div>
</template>
<script setup lang="ts">
import { TsTable } from 'tui';
import type { ColumnsType } from '../../../packages/components/src/table/src/types';
const longColumns = [
{ title: '产品编号', key: 'productCode' },
{ title: '产品名称', key: 'productName' },
{ title: '供应商ID', key: 'supplierId' },
{ title: '供应商密钥', key: 'supplierSecret', showOverflowTooltip: true },
{ title: '库存数量', key: 'stockCount' },
{ title: '保质期(天)', key: 'shelfLife' },
{ title: '是否热销', key: 'isHot', render: (row: any) => (row.isHot ? '是' : '否') },
{ title: '是否新品', key: 'isNew', render: (row: any) => (row.isNew ? '是' : '否') },
{ title: '支持配送区域', key: 'deliveryAreas', custom: true, minWidth: 200 },
{ title: '是否包邮', key: 'isFreeShipping', render: (row: any) => (row.isFreeShipping ? '是' : '否') },
{ title: '是否限购', key: 'isLimited', render: (row: any) => (row.isLimited ? '是' : '否') },
{ title: '商品类型', key: 'productType' },
{ title: '上架时间', key: 'createdAt' },
{ title: '更新时间', key: 'updatedAt' },
{ title: '操作', key: 'expand', custom: true, fixed: 'right' },
] satisfies ColumnsType<any>[];
const fixedColumns = [
{ title: '', key: 'selection', width: 68, fixed: 'left' },
{ title: '产品编号', key: 'productCode', width: 140, fixed: 'left' },
{ title: '产品名称', key: 'productName', width: 180, fixed: 'left' },
{ title: '供应商ID', key: 'supplierId', width: 120 },
{ title: '供应商密钥', key: 'supplierSecret', width: 260, showOverflowTooltip: true },
{ title: '库存数量', key: 'stockCount', width: 120 },
{ title: '保质期(天)', key: 'shelfLife', width: 130 },
{ title: '是否热销', key: 'isHot', width: 120, render: (row: any) => (row.isHot ? '是' : '否') },
{ title: '是否新品', key: 'isNew', width: 120, render: (row: any) => (row.isNew ? '是' : '否') },
{ title: '支持配送区域', key: 'deliveryAreas', custom: true, width: 260 },
{ title: '是否包邮', key: 'isFreeShipping', width: 120, render: (row: any) => (row.isFreeShipping ? '是' : '否') },
{ title: '是否限购', key: 'isLimited', width: 120, render: (row: any) => (row.isLimited ? '是' : '否') },
{ title: '商品类型', key: 'productType', width: 140 },
{ title: '上架时间', key: 'createdAt', width: 180 },
{ title: '更新时间', key: 'updatedAt', width: 180, fixed: 'right' },
{ title: '操作', key: 'actions', custom: true, width: 160, fixed: 'right' },
] satisfies ColumnsType<any>[];
const longDataSource = [
{
productId: 'p10002',
productCode: 'PRD-002',
productName: '蓝牙耳机 AirLite',
supplierId: 'SUP-101',
supplierSecret: 'sec-xyz789qwxyz789qweisiajakkeisiajakk',
deliveryAreas: ['华北', '东北', '西北', '华中'],
isHot: false,
isNew: true,
isFreeShipping: false,
isLimited: true,
stockCount: 50,
shelfLife: 180,
productType: '音频设备',
createdAt: '2025-02-01 09:12:45',
updatedAt: '2025-03-21 11:00:00',
},
{
productId: 'p10003',
productCode: 'PRD-003',
productName: '空气净化器 Pro',
supplierId: 'SUP-102',
supplierSecret: 'sec-555aaa7770555aaa77708s82jskak8s82jskak',
deliveryAreas: ['全国'],
isHot: true,
isNew: true,
isFreeShipping: true,
isLimited: false,
stockCount: 300,
shelfLife: 720,
productType: '家用电器',
createdAt: '2025-02-10 14:35:20',
updatedAt: '2025-03-22 13:25:56',
},
{
productId: 'p10003',
productCode: 'PRD-003',
productName: '空气净化器 Pro',
supplierId: 'SUP-102',
supplierSecret: 'sec-555aaa7770555aaa77708s82jskak8s82jskak',
deliveryAreas: ['全国'],
isHot: true,
isNew: true,
isFreeShipping: true,
isLimited: false,
stockCount: 300,
shelfLife: 720,
productType: '家用电器',
createdAt: '2025-02-10 14:35:20',
updatedAt: '2025-03-22 13:25:56',
},
];
const longDataSSource = Array.from({ length: 1000 }).map((_, index) => ({
...longDataSource[0],
productId: `p${1 + index}`,
productCode: `PRD-${1 + index}`,
productName: `商品 ${1 + index}`,
createdAt: `2025-02-${10 + (index % 20)} 14:35:20`,
updatedAt: `2025-03-${10 + (index % 20)} 13:25:56`,
}));
</script>
<style scoped>
.demo-group + .demo-group {
margin-top: 16px;
}
.demo-title {
margin-bottom: 8px;
font-size: 13px;
font-weight: 600;
}
.demo-tip {
margin-bottom: 10px;
color: #666;
line-height: 1.6;
font-size: 12px;
}
.tag-wrap {
height: 100%;
display: flex;
align-items: center;
column-gap: 6px;
}
.actions-text {
color: #409eff;
white-space: nowrap;
}
</style>