vxe-table实现无缝无限滚动

294 阅读2分钟

注意事项:

  • 表格数据要复制2倍
  • 要用css隐藏滚动条
  • 最好能事先判断下在原本的数据量下,是否能滚动,只有原始数据量下有滚动,无缝无限滚动才有开启的必要
<template>
  <div style="height:290px;" class="vxe-grid-table-wrapper">
    <vxe-grid v-bind="gridOptions" ref="vxeGridRef"></vxe-grid>
  </div>
</template>

<script lang="ts" setup>
import { onBeforeUnmount, onMounted, reactive, ref } from 'vue'
import type { VxeGridComponent, VxeGridProps } from 'vxe-table'

interface RowVO {
  id: number
  name: string
  role: string
  sex: string
  age: number
  address: string
}

const gridOptions = reactive<VxeGridProps<RowVO>>({
  height:'100%',
  columns: [
    { field: 'name', title: 'Name' },
    { field: 'sex', title: 'Sex' },
    { field: 'age', title: 'Age' }
  ],
  data: [
    { id: 10001, name: 'Test1', role: 'Develop', sex: 'Man', age: 28, address: 'test abc' },
    { id: 10002, name: 'Test2', role: 'Test', sex: 'Women', age: 22, address: 'Guangzhou' },
    { id: 10003, name: 'Test3', role: 'PM', sex: 'Man', age: 32, address: 'Shanghai' },
    { id: 10004, name: 'Test4', role: 'Designer', sex: 'Women', age: 24, address: 'Shanghai' },
    { id: 10005, name: 'Test5', role: 'Designer', sex: 'Women', age: 24, address: 'Shanghai' },
    { id: 10006, name: 'Test6', role: 'Designer', sex: 'Women', age: 24, address: 'Shanghai' },
    { id: 10007, name: 'Test7', role: 'Designer', sex: 'Women', age: 24, address: 'Shanghai' },
    { id: 10008, name: 'Test8', role: 'Designer', sex: 'Women', age: 24, address: 'Shanghai' },
    { id: 10009, name: 'Test9', role: 'Designer', sex: 'Women', age: 24, address: 'Shanghai' },
    { id: 10010, name: 'Test10', role: 'Designer', sex: 'Women', age: 24, address: 'Shanghai' },
    { id: 10001, name: 'Test1', role: 'Develop', sex: 'Man', age: 28, address: 'test abc' },
    { id: 10002, name: 'Test2', role: 'Test', sex: 'Women', age: 22, address: 'Guangzhou' },
    { id: 10003, name: 'Test3', role: 'PM', sex: 'Man', age: 32, address: 'Shanghai' },
    { id: 10004, name: 'Test4', role: 'Designer', sex: 'Women', age: 24, address: 'Shanghai' },
    { id: 10005, name: 'Test5', role: 'Designer', sex: 'Women', age: 24, address: 'Shanghai' },
    { id: 10006, name: 'Test6', role: 'Designer', sex: 'Women', age: 24, address: 'Shanghai' },
    { id: 10007, name: 'Test7', role: 'Designer', sex: 'Women', age: 24, address: 'Shanghai' },
    { id: 10008, name: 'Test8', role: 'Designer', sex: 'Women', age: 24, address: 'Shanghai' },
    { id: 10009, name: 'Test9', role: 'Designer', sex: 'Women', age: 24, address: 'Shanghai' },
    { id: 10010, name: 'Test10', role: 'Designer', sex: 'Women', age: 24, address: 'Shanghai' }
  ]
})

let timer:number|undefined
const vxeGridRef = ref<VxeGridComponent>()

/**
 * # 能够显示markdown注释
 *
 * ```json
 * {
 *  “name”: "张三"
 * }
 * ```
 */
function autoCycle(){
  // .vxe-table--body-wrapper
  const tableBodyWrapper:HTMLDivElement | undefined = vxeGridRef.value?.$el.querySelector('.vxe-table--body-wrapper');
  if(tableBodyWrapper){
    timer = window.setInterval(() => {
      // 元素自增距离顶部1像素
      tableBodyWrapper.scrollTop += 1
      // 判断元素是否滚动到底部(可视高度+距离顶部=整个高度)
      if (tableBodyWrapper.clientHeight + tableBodyWrapper.scrollTop === tableBodyWrapper.scrollHeight) {
        // 重置table距离顶部距离。值=(滚动到底部时,距离顶部的大小) - 整个高度/2
        tableBodyWrapper.scrollTop = tableBodyWrapper.scrollTop - tableBodyWrapper.scrollHeight/2
      }
    }, 50)
  }
}

onMounted(()=>{
  requestAnimationFrame(()=>{
    autoCycle()
  })
})

onBeforeUnmount(()=>{
  if(timer){
    window.clearInterval(timer)
  }
})
</script>
<style>
.vxe-grid-table-wrapper .vxe-table--body-wrapper::-webkit-scrollbar {
  display: none;
}
.vxe-grid-table-wrapper .vxe-table--body-wrapper{
  scrollbar-width: none; /* firefox */
  -ms-overflow-style: none; /* IE 10+ */
}
</style>