2
2
* item component, we need to know their size change at any time
3
3
*/
4
4
5
- import { cloneVNode , computed , defineComponent , ref } from 'vue' ;
5
+ import { cloneVNode , computed , defineComponent , onBeforeUnmount , ref } from 'vue' ;
6
6
import useResize from '../_util/use/useResize' ;
7
7
import { getFirstValidNode } from '../_util/vnode' ;
8
8
import getElementFromVueInstance from '../_util/getElementFromVueInstance' ;
@@ -14,20 +14,51 @@ export const FVirtualListItem = defineComponent({
14
14
props : itemProps ,
15
15
setup ( props , { attrs } ) {
16
16
const itemRef = ref ( ) ;
17
+ let lastReportedSize = 0 ;
18
+ let sizeCheckTimer : number | null = null ;
17
19
18
- // tell parent current size identify by unqiue key
20
+ // 优化的尺寸变化检测和上报
19
21
const dispatchSizeChange = ( ) => {
22
+ if ( ! itemRef . value ) {
23
+ return ;
24
+ }
25
+
20
26
const shapeKey = props . horizontal ? 'offsetWidth' : 'offsetHeight' ;
21
- const s = itemRef . value ? itemRef . value [ shapeKey ] : 0 ;
22
- ( attrs as any ) . onItemResized ( props . uniqueKey , s ) ;
27
+ const currentSize = itemRef . value [ shapeKey ] || 0 ;
28
+
29
+ // 只有当尺寸显著变化时才上报,避免频繁的微小变化
30
+ // 阈值可以根据实际情况调整,例如设置为2px
31
+ const sizeThreshold = 2 ;
32
+ if ( Math . abs ( currentSize - lastReportedSize ) >= sizeThreshold ) {
33
+ lastReportedSize = currentSize ;
34
+ ( attrs as any ) . onItemResized ( props . uniqueKey , currentSize ) ;
35
+ }
23
36
} ;
24
37
38
+ // 防抖的尺寸检查,并确保在组件卸载时清除定时器
39
+ const debouncedSizeCheck = ( ) => {
40
+ if ( sizeCheckTimer ) {
41
+ clearTimeout ( sizeCheckTimer ) ;
42
+ }
43
+ // 稍微增加延迟,减少高频触发,例如 30ms
44
+ sizeCheckTimer = setTimeout ( dispatchSizeChange , 16 ) as any ;
45
+ } ;
46
+
47
+ // 使用原有的useResize,但添加防抖
25
48
useResize (
26
49
itemRef ,
27
- dispatchSizeChange ,
50
+ debouncedSizeCheck ,
28
51
computed ( ( ) => ! props . observeResize ) ,
29
52
) ;
30
53
54
+ // 清理定时器
55
+ onBeforeUnmount ( ( ) => {
56
+ if ( sizeCheckTimer ) {
57
+ clearTimeout ( sizeCheckTimer ) ;
58
+ sizeCheckTimer = null ;
59
+ }
60
+ } ) ;
61
+
31
62
return {
32
63
itemRef,
33
64
} ;
0 commit comments