虛擬滾動勾子
import { ref, reactive, watch,isRef,nextTick } from "vue";
export const useVirtualList = (dataLen, config) => {
let { start = 0, end, itemHeight, className, tableHeight } = config || {};
const virtualList = reactive({
start,
end,
itemHeight,
tableHeight,
className,
currentOffset: 0,
wrapperDom: null,
contentDom: null,
});
const isDynamicHeight = isRef(tableHeight);
virtualList.end = end || parseInt((isDynamicHeight ? tableHeight.value : tableHeight) / itemHeight);
virtualList.count = virtualList.end - start;
className = `${virtualList.className ? "." + virtualList.className + " " : ""}`;
const init = () => {
virtualList.wrapperDom = document.querySelector(`${className}.ant-table-body`);
virtualList.contentDom = document.querySelector(`${className}.ant-table-body table`);
if (!virtualList.wrapperDom || !virtualList.contentDom) return;
virtualList.wrapperDom.style.position = "relative";
virtualList.wrapperDom.style.top = virtualList.wrapperDom.style.left = "0";
virtualList.contentDom.style.position = "absolute";
virtualList.wrapperDom.addEventListener("scroll", handleScroll);
let isExist = document.querySelector(`${className}.palceholder-dom`);
if (isExist) virtualList.wrapperDom?.removeChild(isExist);
const placeHolderDom = document.createElement("div");
placeHolderDom.className = "palceholder-dom";
virtualList.wrapperDom.appendChild(placeHolderDom);
placeHolderDom.style.height = dataLen * virtualList.itemHeight + "px";
};
const handleScroll = () => {
const scrollTop = virtualList.wrapperDom.scrollTop;
virtualList.start = Math.ceil(scrollTop / virtualList.itemHeight);
virtualList.end = virtualList.start + virtualList.count;
virtualList.currentOffset = scrollTop - (scrollTop % virtualList.itemHeight);
virtualList.contentDom.style.transform = `translateY(${virtualList.currentOffset}px)`;
};
nextTick(() => {
init();
});
return virtualList;
};
頁面使用
import { useVirtualList } from "@/use/useVirtualList";
watch(tableData, () => {
virtualList.value = useVirtualList(tableData.value.length, {
end:14,
className: 's-table',
itemHeight: 71,
});
})
const showData = computed(() => tableData.value.slice(virtualList.value.start, virtualList.value.end))
<s-table class="s-table" :columns="columns" :data-source="showData" :pagination="false" :scrollX="2500">