使用vue3和vue3-seamless-scroll封装滚动表格组件

发布于:2025-04-17 ⋅ 阅读:(83) ⋅ 点赞:(0)

实现效果:

说明:序号需要自己在数组中添加,无法使用customRender函数,因滚动组件css无法作用在行内,所以引用页需要自行设置高度

  :deep(.scroll) {

    height: 170px !important;

  }

使用案例:

   <newTable
          :columns="columns"
          :data-source="dataList"
          :limitScrollNum="5"
          :scrollY="168"
          :tableRefName="`riskEvent`"
      />

代码:

<!-- 使用 vue3-seamless-scroll 封装table表格 -->
<template>
  <div style="width: 100%">
    <div class="thead-dom">
      <div
        v-for="(item, index) in columns"
        :key="index"
        :style="{
          ...(item.width ? { width: item.width + 'px' } : { flex: 1 }),
          // 添加固定的额外样式属性
          textAlign: (item?.align as any) || 'left',
        }"
      >
        {{ item?.title }}
      </div>
    </div>
    <div v-if="dataSource.length > 0">
      <vue3-seamless-scroll
        :list="dataSource"
        class="scroll"
        direction="up"
        :step="2"
        :hover="true"
        :limit-scroll-num="limitScrollNum"
        :is-watch="true"
        :single-height="singleHeight"
        :single-width="0"
        :single-wait-time="singleWaitTime"
        :wheel="true"
      >
        <div class="list-dom" v-for="(item, index) in dataSource" @click="rowClick(item)">
          <div
            v-for="(v, VIndex) in columns"
            :key="VIndex"
            :style="{
              ...(v?.width ? { width: v?.width + 'px' } : { flex: 1 }),
              // 添加固定的额外样式属性
              textAlign: (v?.align as any) || 'left',
            }"
          >
            <!-- 判断指定名称的插槽是否存在 -->
            <template v-if="$slots[v.dataIndex]">
              <slot
                :name="v.dataIndex"
                :record="item"
                :index="index"
                :text="item[v?.dataIndex]"
              ></slot>
            </template>
            <template v-else>
              {{ item[v?.dataIndex as string] }}
            </template>
          </div>
        </div>
      </vue3-seamless-scroll>
    </div>
    <div
      v-if="dataSource.length === 0"
      class="null-dom"
      :style="{
        height: scrollY + 'px',
      }"
    >
      <img src="../../assets/images/nullData.png" alt="" style="width: 65px; margin-bottom: 8px" />
      <div style="height: 20px">暂无数据</div>
    </div>
    <!--  -->
  </div>
</template>

<script lang="ts" setup>
import { Util } from "@msa/msa-core";
import { Vue3SeamlessScroll } from "vue3-seamless-scroll";
import { ref, onMounted, onBeforeUnmount, onUpdated, toRefs, watch, nextTick } from "vue";

interface Columns {
  title: string;
  dataIndex: string;
  width?: number;
  align?: string;
  ellipsis?: boolean;
}
const emits = defineEmits(["rowClick", "myEcharts"]);

const props = defineProps({
  // 如果有宽度,以百分百传入
  columns: {
    type: Array<Columns>,
    default: () => [],
  },
  dataSource: {
    type: Array<any>,
    default: () => [],
  },
  limitScrollNum: {
    type: Number,
    default: 5, // 默认的起始条数
  },
  scrollY: {
    type: Number,
    default: 300, // 默认的起始条数
  },
  singleHeight: {
    type: Number,
    default: 34, // 默认的起始条数
  },
  singleWaitTime: {
    type: Number,
    default: 3000, // 默认的起始条数
  },
  loading: {
    type: Boolean,
    default: false,
  },
});

const { columns, dataSource, limitScrollNum, scrollY, singleHeight, singleWaitTime } =
  toRefs(props);

const isScroll = ref<any>(null);
watch(
  () => dataSource.value,
  () => {
    isScroll.value = false;
    isScroll.value = true;
  },
  {
    deep: true,
  },
);

const rowClick = (item: any) => {
  emits("rowClick", item);
};
</script>

<style lang="less" scoped>
.thead-dom {
  display: flex;
  color: #698eb5;
  font-size: 12px !important;
  justify-content: space-between;
  align-items: center;
  height: 34px;
  background: #0c315a;
  border-top-left-radius: 5px;
  border-top-right-radius: 5px;
}

.null-dom {
  width: 100%;
  display: flex;
  justify-content: center;
  flex-direction: column;
  align-items: center;
  color: #c8cbd8;
}

.list-dom {
  height: 34px;
  display: flex;
  // justify-content: space-around;
  align-items: center;
  font-weight: 500;
  font-size: 14px;
  color: #fff;
  background: #0e3962;
  border-top: 1px solid #1c4265 !important;
  // .row-list {
  //   height: 34px;
  //   overflow: hidden;
  //   display: flex;
  //   // align-items: center;
  //   cursor: pointer;
  // }
  &:hover {
    color: #46e9f7;
  }
}
.scroll {
  height: 100px;
  overflow: hidden;
}
.list-dom:nth-child(2n) {
  background: #0c2f55;
}
</style>


网站公告

今日签到

点亮在社区的每一天
去签到