export const ranges = ref({ from: 0, to: 0 }); // 数据取值范围
export const placeholderHeight = computed(() => ({
head: ranges.value.from * ITEM_HEIGHT + "px",
// 将不展示的数据过滤, 防止隐藏的数据参与计算导致页面渲染的元素不正确的问题
const source = computed(() =>
tableViewData.value.filter((row) => getConfigOfRowKey(row).display)
const getViewCapacity = (containerHeight) => {
return Math.ceil(containerHeight / ITEM_HEIGHT);
const getOffset = (scrollTop) => {
return Math.floor(scrollTop / ITEM_HEIGHT) + 1;
export const calculateRange = () => {
const element = containerRef.value;
const offset = getOffset(element.scrollTop);
const viewCapacity = getViewCapacity(element.clientHeight - 38 - 7); // 表头高度 + 横向滚动条高度
const start = offset - OVER_SCAN;
const end = offset + viewCapacity + OVER_SCAN;
from: start < 0 ? 0 : start,
to: end > source.value.length ? source.value.length : end,
renderViewData.value = source.value.slice(
// 当容器的高度或者数据源变化则重新计算数据区间
[size.height, tableViewData],
debounce(() => calculateRange(), 200)