UNPKG

@fesjs/fes-design

Version:
88 lines (79 loc) 2.54 kB
import { defineComponent, ref, computed, onBeforeUnmount, cloneVNode } from 'vue'; import useResize from '../_util/use/useResize'; import { getFirstValidNode } from '../_util/vnode'; import getElementFromVueInstance from '../_util/getElementFromVueInstance'; import { itemProps } from './props'; /** * item component, we need to know their size change at any time */ // wrapping for item const FVirtualListItem = defineComponent({ name: 'FVirtualListItem', props: itemProps, setup(props, _ref) { let { attrs } = _ref; const itemRef = ref(); let lastReportedSize = 0; let sizeCheckTimer = null; // 优化的尺寸变化检测和上报 const dispatchSizeChange = () => { if (!itemRef.value) { return; } const shapeKey = props.horizontal ? 'offsetWidth' : 'offsetHeight'; const currentSize = itemRef.value[shapeKey] || 0; // 只有当尺寸显著变化时才上报,避免频繁的微小变化 // 阈值可以根据实际情况调整,例如设置为2px const sizeThreshold = 2; if (Math.abs(currentSize - lastReportedSize) >= sizeThreshold) { lastReportedSize = currentSize; attrs.onItemResized(props.uniqueKey, currentSize); } }; // 防抖的尺寸检查,并确保在组件卸载时清除定时器 const debouncedSizeCheck = () => { if (sizeCheckTimer) { clearTimeout(sizeCheckTimer); } // 稍微增加延迟,减少高频触发,例如 30ms sizeCheckTimer = setTimeout(dispatchSizeChange, 16); }; // 使用原有的useResize,但添加防抖 useResize(itemRef, debouncedSizeCheck, computed(() => !props.observeResize)); // 清理定时器 onBeforeUnmount(() => { if (sizeCheckTimer) { clearTimeout(sizeCheckTimer); sizeCheckTimer = null; } }); return { itemRef }; }, render() { var _$slots$default, _$slots$default2; const { index, source, $slots } = this; const vNode = getFirstValidNode((_$slots$default = (_$slots$default2 = $slots.default) === null || _$slots$default2 === void 0 ? void 0 : _$slots$default2.call($slots, { index, source })) !== null && _$slots$default !== void 0 ? _$slots$default : []); if (!vNode) { return; } return cloneVNode(vNode, { ref: el => { if (el) { this.itemRef = getElementFromVueInstance(el); } } }, true); } }); export { FVirtualListItem };