<template>
<div class="monitor-table-container">
<table class="monitor-table">
<thead>
<th v-for="(item, index) in props.columns" :key="index" :style="`width:${item?.width};`">
<span v-if="!item?.isSelect"> {{ item.label }}</span>
<Select
v-else
@select="item?.change"
:default-value="item?.options && item?.options[0]?.value"
v-model:value="item[item.field + 'SelectValue']"
style="width: 100%"
>
<SelectOption v-for="(opt, idx) in item.options" :key="idx" :value="opt.value">{{ opt.label }}</SelectOption>
</Select>
</th>
</thead>
<tbody
:ref="(e) => getHeight(e, index)"
:style="`margin-top:${index === 1 ? '37px' : 0};`"
:class="tbodyNum > 1 ? 'tbody-animation my-tbody' : 'my-tbody'"
v-for="index in tbodyNum"
:key="index"
>
<tr v-for="item in props.data" :key="item">
<td :style="`width:${column?.width};`" v-for="column in props.columns" :key="column.field">
<slot :record="item" :value="item[column.field]" :field="column.field"></slot>
<span v-if="!slots?.default">
{{ item[column.field] === null || item[column.field] === undefined ? '--' : item[column.field] }}
</span>
</td>
</tr>
</tbody>
</table>
<Empty style="margin-top: 20px" v-if="!props?.data?.length" />
</div>
</template>
<script setup lang="ts">
import { ref, useSlots } from 'vue'
import { Select, SelectOption, Empty } from 'ant-design-vue'
interface Columns {
label: string
field: string
width?: string
isSelect?: boolean
options?: any[]
change?: (value: any) => void
}
const slots = useSlots()
const props = defineProps<{ columns: Columns[]; data: any[] }>()
const tbodyNum = ref(1)
const getHeight = (e, index) => {
const container = document.getElementsByClassName('monitor-table-container')[0]
if (index === 1 && e?.clientHeight !== 0) {
tbodyNum.value = e?.clientHeight > container.clientHeight - 37 ? 2 : 1
}
}
</script>
<style scoped lang="less">
@keyframes scroll {
0% {
transform: translateY(0);
}
100% {
transform: translateY(calc(-100% + 10px));
}
}
table thead,
tbody tr {
display: table;
table-layout: fixed;
width: 100%;
}
.monitor-table-container {
width: 400px;
height: 100%;
overflow: hidden;
}
::v-deep .ant-select-focused {
.ant-select-selector {
background-color: transparent !important;
border: none !important;
border: 0;
box-shadow: none !important;
.ant-select-selection-item {
color: black !important;
}
}
}
::v-deep .ant-select {
height: 20px;
margin-top: 2px;
display: flex;
align-items: center;
.ant-select-arrow {
padding-left: 8px;
}
.ant-select-selection-item {
color: #333 !important;
font-weight: bold;
}
.ant-select-selector {
border-radius: 0;
background-color: transparent;
padding: 0;
border: 0;
}
}
.monitor-table {
position: relative;
width: 100%;
thead {
position: absolute;
z-index: 1;
background: rgb(223, 239, 254);
th {
text-align: center;
padding: 8px 16px 7px 16px;
color: rgba(51, 51, 51, 1);
}
}
.tbody-animation {
animation: scroll 30s linear infinite;
}
tbody {
z-index: 0;
display: block;
tr {
border-bottom: 1px solid rgba(153, 153, 153, 0.2);
td {
text-align: center;
padding: 8px 16px 7px 16px;
color: rgba(51, 51, 51, 1);
}
}
}
}
</style>
table元素纯css无限滚动,流畅过度
于 2024-11-19 11:02:30 首次发布