vue3+iview的Table,实现表格自动滚动
主要代码:
const startAutoScroll = () => {
intervalId.value && clearInterval(intervalId.value)
intervalId.value = setInterval(() => {
if (!containerRef.value) return
// 使用类型断言来确保 TypeScript 识别 tableRef 属性
let target = (containerRef.value as any).tableRef?.$el.querySelector('.ivu-table-body')
target.scrollTop += 40 // 滚动两行的高度(假设行高25px)
console.log('自动滚动控制', target.scrollTop)
// 滚动到底部检测
if (target.scrollTop + target.clientHeight >= target.scrollHeight - 10) {
pagination.current++
getTableData()
}
}, 1500)
}
const getTableData = async () => {
if (loading.value) return
loading.value = true
try {
const res = await api({
index: pagination.current,
size: pagination.pageSize,
})
console.log('表格数据', res)
tableData.value = formatResult ? formatResult(res) : res.records
// 自动滚动控制
if (autoScroll) {
startAutoScroll()
}
// 分页循环逻辑
if (tableData.value && tableData.value?.length < pagination.pageSize) {
pagination.current = 1 // 重置到第一页
let target = (containerRef.value as any).tableRef?.$el.querySelector('.ivu-table-body')
target.scrollTop = 0 // 滚动两行的高度(假设行高25px)
await nextTick()
await getTableData() // 立即重新获取
}
setTotal(res.total)
onSuccess && onSuccess()
} catch (error) {
//
} finally {
loading.value = false
}
}
全部文件:
useTable.ts
import { usePagination } from '@/compositionAPI/table/usePagination'
import { useDebounceFn } from '@vueuse/core'
import { ElMessage, ElMessageBox, ElLoading } from 'element-plus'
interface Options<T> {
formatResult?: (data: T[]) => any
onSuccess?: () => void
immediate?: boolean
rowKey?: keyof T
moduleUrl?: string //接口前缀
autoScroll?: boolean //自动滚动到顶部
}
export const useTable = <T>(api: any, options?: Options<T>) => {
const { formatResult, onSuccess, immediate, rowKey, moduleUrl, autoScroll } = options || {}
const { pagination, setTotal } = usePagination(() => getTableData())
const loading = ref(false)
const tableData = ref([])
// const intervalId = ref<NodeJS.Timeout>()
const intervalId = ref<number>()
const containerRef = ref<HTMLElement>()
// const getTableData = useDebounceFn(async () => {
const getTableData = async () => {
if (loading.value) return
loading.value = true
try {
const res = await api({
index: pagination.current,
size: pagination.pageSize,
})
console.log('表格数据', res)
tableData.value = formatResult ? formatResult(res) : res.records
// 自动滚动控制
if (autoScroll) {
startAutoScroll()
}
// 分页循环逻辑
if (tableData.value && tableData.value?.length < pagination.pageSize) {
pagination.current = 1 // 重置到第一页
let target = (containerRef.value as any).tableRef?.$el.querySelector('.ivu-table-body')
target.scrollTop = 0 // 滚动两行的高度(假设行高25px)
await nextTick()
await getTableData() // 立即重新获取
}
setTotal(res.total)
onSuccess && onSuccess()
} catch (error) {
//
} finally {
loading.value = false
}
}
// }, 500)
// 自动滚动实现
const startAutoScroll = () => {
intervalId.value && clearInterval(intervalId.value)
intervalId.value = setInterval(() => {
if (!containerRef.value) return
// 使用类型断言来确保 TypeScript 识别 tableRef 属性
let target = (containerRef.value as any).tableRef?.$el.querySelector('.ivu-table-body')
target.scrollTop += 40 // 滚动两行的高度(假设行高25px)
console.log('自动滚动控制', target.scrollTop)
// 滚动到底部检测
if (target.scrollTop + target.clientHeight >= target.scrollHeight - 10) {
pagination.current++
getTableData()
}
}, 1500)
}
// 清理定时器
onUnmounted(() => {
intervalId.value && clearInterval(intervalId.value)
})
getTableData()
return {
loading,
tableData,
getTableData,
pagination,
containerRef,
}
}
MainTbl.vue 重点 ref:tableRef
<template>
<Table
:columns="columnsVM"
:data="data"
:loading="loading"
ref="tableRef"
draggable
:class="ns.e('table')"
v-bind="$attrs"
id="tableRef"
:height="height || heightTableNumb"
>
<!-- -->
<!-- 操作栏 -->
<template #action="scope">
<ActionBtns :scope="scope"></ActionBtns>
</template>
<template #[slotName]="slotProps" v-for="(slot, slotName) in $slots">
<slot :name="slotName" v-bind="slotProps" />
</template>
</Table>
<Page
v-if="Object.keys(pagination).length"
v-model="paginationVM.current"
:total="paginationVM.total"
:page-size="paginationVM.pageSize"
size="small"
show-elevator
show-sizer
show-total
@on-change="paginationVM.onChange"
@on-page-size-change="paginationVM.onPagesizechange"
ref="pageRef"
/>
</template>
使用ParkCompany.vue,引入:MainTbl
<template>
<MainTbl
ref="containerRef"
:data="tableData"
v-model:columns="columns"
:loading="loading"
:showIndex="false"
:height="contentH"
>
</MainTbl>
......
import MainTbl from '@/components/common/mainTbl/MainTbl.vue'
......
</template>

浙公网安备 33010602011771号