|
4 | 4 | @scroll="handleScroll" |
5 | 5 | class="video-scroll-container" |
6 | 6 | ref="scrollbarRef" |
7 | | - :style="'height:' + scrollAreaHeight + 'px; overflow: auto;'" |
| 7 | + :style="{ height: containerHeightRef + 'px', overflow: 'auto' }" |
8 | 8 | > |
9 | 9 | <a-grid :cols="{ xs: 2, sm: 3, md: 4, lg: 5, xl: 6, xxl: 8 }" :rowGap="16" :colGap="12"> |
10 | 10 | <a-grid-item |
@@ -139,7 +139,9 @@ const router = useRouter(); |
139 | 139 | const visitedStore = useVisitedStore(); |
140 | 140 | const containerRef = ref(null); |
141 | 141 | const scrollbarRef = ref(null); |
142 | | -const scrollAreaHeight = ref(0); |
| 142 | +// 使用非响应式变量避免递归更新 |
| 143 | +let containerHeight = 0; |
| 144 | +const containerHeightRef = ref(0); |
143 | 145 |
|
144 | 146 | // ActionRenderer相关 |
145 | 147 | const actionRendererRef = ref(null); |
@@ -331,8 +333,9 @@ const updateScrollAreaHeight = () => { |
331 | 333 | const newHeight = Math.max(containerHeight - footerHeight - heightReduction, 250); // 降低最小高度 |
332 | 334 | |
333 | 335 | // 只有当高度真正发生变化时才更新 |
334 | | - if (Math.abs(scrollAreaHeight.value - newHeight) > 5) { |
335 | | - scrollAreaHeight.value = newHeight; |
| 336 | + if (Math.abs(containerHeight - newHeight) > 5) { |
| 337 | + containerHeight = newHeight; |
| 338 | + containerHeightRef.value = newHeight; |
336 | 339 | } |
337 | 340 | |
338 | 341 | console.log(`视频数量: ${videoCount}, 估算行数: ${estimatedRows}, 列数: ${gridCols}, 容器宽度: ${containerWidth}px, 最终高度: ${newHeight}px`); |
@@ -452,29 +455,44 @@ onBeforeUnmount(() => { |
452 | 455 | let updateTimer = null; |
453 | 456 | let lastVideosLength = 0; |
454 | 457 | let lastShowStats = false; |
| 458 | +let lastVideosHash = ''; |
| 459 | +
|
| 460 | +// 计算videos数组的简单hash |
| 461 | +const getVideosHash = (videos) => { |
| 462 | + if (!videos || videos.length === 0) return ''; |
| 463 | + return videos.map(v => v.vod_id || '').join(','); |
| 464 | +}; |
455 | 465 |
|
456 | 466 | watch([() => props.videos, () => props.showStats], ([newVideos, newShowStats]) => { |
457 | | - // 避免不必要的更新 |
458 | | - if (newVideos.length === lastVideosLength && newShowStats === lastShowStats) { |
| 467 | + const newVideosHash = getVideosHash(newVideos); |
| 468 | + |
| 469 | + // 更严格的条件检查,避免不必要的更新 |
| 470 | + if (newVideos.length === lastVideosLength && |
| 471 | + newShowStats === lastShowStats && |
| 472 | + newVideosHash === lastVideosHash) { |
459 | 473 | return; |
460 | 474 | } |
461 | 475 | |
462 | 476 | lastVideosLength = newVideos.length; |
463 | 477 | lastShowStats = newShowStats; |
| 478 | + lastVideosHash = newVideosHash; |
464 | 479 | |
465 | 480 | // 清除之前的定时器 |
466 | 481 | if (updateTimer) { |
467 | 482 | clearTimeout(updateTimer); |
468 | 483 | } |
469 | 484 | |
470 | | - // 使用防抖避免频繁更新 |
| 485 | + // 使用防抖避免频繁更新,增加延迟 |
471 | 486 | updateTimer = setTimeout(() => { |
472 | | - nextTick(() => { |
473 | | - checkTextOverflow(); |
474 | | - updateScrollAreaHeight(); |
475 | | - }); |
476 | | - }, 100); |
477 | | -}, { deep: true }); |
| 487 | + // 再次检查是否需要更新,避免组件已卸载时的更新 |
| 488 | + if (containerRef.value && !isUpdatingHeight && !isCheckingOverflow) { |
| 489 | + nextTick(() => { |
| 490 | + checkTextOverflow(); |
| 491 | + updateScrollAreaHeight(); |
| 492 | + }); |
| 493 | + } |
| 494 | + }, 200); // 增加延迟到200ms |
| 495 | +}, { deep: false }); // 移除deep监听,减少触发频率 |
478 | 496 |
|
479 | 497 | // 滚动位置恢复方法 |
480 | 498 | const restoreScrollPosition = (scrollPosition) => { |
|
0 commit comments