table元素纯css无限滚动,流畅过度

在这里插入图片描述

<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>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值