@fesjs/fes-design
Version:
fes-design for PC
88 lines (79 loc) • 2.54 kB
JavaScript
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 };