效果图:
实现代码如下:
<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>