纵向无限滚动
单元格内部横向滚动
<!--
* @Description: 横向、纵向滚动表格
* @Author: liyanfeng liyanfeng@hopewind.com
* @Date: 2024-06-15 16:06:57
* @LastEditors: liyanfeng liyanfeng@hopewind.com
* @LastEditTime: 2024-06-20 17:15:37
* @FilePath: \plus-ui\src\components\ScrollTable\index.vue
* Copyright 2024 Shenzhen Hopewind Electric Co., Ltd, All RightsReserved.
-->
<template>
<div class="scroll-table">
<div class="scroll-table-header">
<div
v-for="item in header"
:key="item.props"
class="scroll-table-header-item"
:style="{ width: item.width }"
>{{ item.name }}</div
>
</div>
<div class="scroll-table-body">
<div class="scroll-table-body-content" :class="{ bodyScroll }">
<div class="content-item" v-for="item in scrollData" :key="item.id">
<div
class="content-cell"
v-scroll
v-for="col in header"
:key="col.props"
:style="{ width: col.width }"
>
<div class="content-scroll">
<template v-if="col.slot">
<slot :name="col.slot" :scope="item"></slot>
</template>
<template v-else>
{{ item[col.props] || '--' }}
</template>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import type { Header } from './types';
interface Props {
header: Header[];
data: any;
bodyScroll?: boolean; // 是否纵向滚动
height?: number; // 高度
listNum?: number; // 每页数据量
}
const prop = defineProps<Props>();
const scrollData = computed(() => {
return prop.data.concat(prop.data.slice(0, prop.listNum || 7));
});
const vScroll = {
mounted: (el: HTMLElement) => {
if (el.scrollWidth !== el.clientWidth) {
el.classList.add('content-scroll-father');
}
},
};
// 纵向滚动距离
const scrollHeight = computed(() => {
return ((prop.height || 280) / 1080) * 100 + 'vh';
});
</script>
<style lang="scss" scoped>
.scroll-table {
width: 100%;
height: 100%;
color: #fff;
}
.scroll-table-header {
display: flex;
align-items: center;
justify-content: space-between;
background: rgba(255, 255, 255, 0.1);
font-size: vw(16);
color: #a8bfcf;
height: vh(40);
&-item {
text-align: center;
}
}
.scroll-table-body {
width: 100%;
height: calc(100% - vh(40));
font-size: vw(14);
overflow: hidden;
}
.scroll-table-body-content {
width: 100%;
}
.bodyScroll {
animation: bodyScroll 20s linear infinite;
&:hover {
animation-play-state: paused;
}
}
@keyframes bodyScroll {
0% {
transform: translateY(0);
}
100% {
transform: translateY(
calc(-100% + v-bind(scrollHeight))
); // 向上偏移自身高度的100% 再减去首屏高度
}
}
.content-item {
display: flex;
align-items: center;
justify-content: space-between;
height: vh(40);
line-height: vh(40);
color: '#A8BFCF';
.content-cell {
white-space: nowrap;
overflow: hidden;
text-align: center;
}
.content-scroll-father .content-scroll {
width: max-content;
animation: cellScroll 5s linear infinite;
}
&:nth-child(even) {
background: rgba(255, 255, 255, 0.1);
}
}
@keyframes cellScroll {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-100%); // 向左偏移自身宽度
}
}
</style>