效果图:
实现代码如下:
<template><div class="scroll-container" @mouseenter="stopScroll" @mouseleave="startScroll"><a-table:columns="columns":data-source="visibleData":pagination="false":scroll="{ y: '300px' }"row-class-name="scroll-row"ref="tableRef"><template #bodyCell="{ column, record, text }"><span>{{ text }}</span></template><template #headerCell="{ column }"><span>{{ column.title }}</span></template></a-table></div></template><script setup lang="ts">import { ref, onMounted, onBeforeUnmount } from "vue";// 定义表格列const columns = [{ title: "序号", dataIndex: "index", key: "index", width: "10%" },{ title: "名称", dataIndex: "projectName", key: "projectName", width: "30%" },{ title: "国别", dataIndex: "projectCountry", key: "projectCountry", width: "15%" },{ title: "总部", dataIndex: "region", key: "region", width: "15%" },{ title: "单位", dataIndex: "orgName", key: "orgName", width: "15%" },{ title: "经理", dataIndex: "projectManager", key: "projectManager", width: "15%" },];const dataSource = ref([{index: 1,projectName: "项目A",projectCountry: "中国",region: "华东",orgName: "组织A",projectManager: "经理A",},{index: 2,projectName: "项目B",projectCountry: "美国",region: "西部",orgName: "组织B",projectManager: "经理B",},{index: 3,projectName: "项目C",projectCountry: "德国",region: "北部",orgName: "组织C",projectManager: "经理C",},{index: 4,projectName: "项目D",projectCountry: "法国",region: "南部",orgName: "组织D",projectManager: "经理D",},{index: 5,projectName: "项目D",projectCountry: "法国",region: "南部",orgName: "组织D",projectManager: "经理D",},{index: 6,projectName: "项目D",projectCountry: "法国",region: "南部",orgName: "组织D",projectManager: "经理D",},{index: 7,projectName: "项目D",projectCountry: "法国",region: "南部",orgName: "组织D",projectManager: "经理D",},{index: 8,projectName: "项目D",projectCountry: "法国",region: "南部",orgName: "组织D",projectManager: "经理D",},// 添加更多数据以测试滚动效果]);const visibleData = ref([...dataSource.value]);const tableRef = ref(null);let scrollInterval: any = null;// 启动滚动const startScroll = () => {if (scrollInterval) return;scrollInterval = setInterval(() => {if (tableRef.value) {const tbody = tableRef.value!.$el.querySelector("tbody") as HTMLElement;const rows = Array.from(tbody.querySelectorAll("tr.scroll-row"));console.log(rows, "22222222222222");if (rows.length === 0) return;const firstRow = rows[0] as HTMLElement;const rowHeight = firstRow ? firstRow.offsetHeight : 0;// 启动动画tbody.style.transition = "transform 0.6s ease-in-out";tbody.style.transform = `translateY(-${rowHeight}px)`;setTimeout(() => {tbody.style.transition = "none";tbody.style.transform = "translateY(0)";if (firstRow) {tbody.appendChild(firstRow); // 将第一行移动到最后}}, 600); // 时间要与 transition 一致}}, 3000); // 每13秒滚动一次};// 停止滚动const stopScroll = () => {if (scrollInterval) {clearInterval(scrollInterval);scrollInterval = null;}};onMounted(() => {startScroll();});onBeforeUnmount(() => {stopScroll();});</script><style scoped lang="less">.scroll-container {// overflow: hidden;position: relative;height: 300px; /* 根据需要调整容器高度 */}.ant-table {width: 100%;border-collapse: collapse;}.ant-table thead {position: sticky;top: 0;background-color: #fff;z-index: 1; /* 确保表头层级高于内容 */}.ant-table tbody {display: block;max-height: 300px; /* 确保 tbody 的高度 */overflow-y: auto; /* 使 tbody 可滚动 */}.ant-table tbody tr {display: table;width: 100%;table-layout: fixed;}.scroll-row {// transition: transform 0.6s ease-in-out;// min-height: 48px; /* 根据需要设置每行的最小高度 */background: red;}.ant-table tbody tr:nth-child(odd) {background-color: #f9f9f9;}.ant-table tbody tr:nth-child(even) {background-color: #fff;}</style>