From 907e158f44d10f64f333332d80fbc796bb2a0d16 Mon Sep 17 00:00:00 2001 From: hanxuanyu <2252193204@qq.com> Date: Tue, 27 Jan 2026 18:38:49 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=89=8D=E7=AB=AF=EF=BC=9A?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E6=97=A0=E9=99=90=E6=BB=9A=E5=8A=A8=E5=8A=A0?= =?UTF-8?q?=E8=BD=BD=E5=8F=8A=E5=89=8D=E5=90=8E=E6=97=A5=E6=9C=9F=E5=8F=AF?= =?UTF-8?q?=E7=94=A8=E6=80=A7=E6=A3=80=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- webapp/src/views/Home.vue | 73 ++++++++++++++++++++++++++-------- webapp/src/views/ImageView.vue | 66 ++++++++++++++++++++++++------ 2 files changed, 109 insertions(+), 30 deletions(-) diff --git a/webapp/src/views/Home.vue b/webapp/src/views/Home.vue index a712f4b..3646875 100644 --- a/webapp/src/views/Home.vue +++ b/webapp/src/views/Home.vue @@ -173,13 +173,18 @@ 加载中... - + +

已加载全部图片 @@ -246,8 +251,8 @@ const router = useRouter() // 获取今日图片 const { image: todayImage, loading: todayLoading } = useTodayImage() -// 获取图片列表(使用服务端分页和筛选) -const { images, loading, hasMore, loadMore, filterByMonth } = useImageList(30) +// 获取图片列表(使用服务端分页和筛选,每页15张) +const { images, loading, hasMore, loadMore, filterByMonth } = useImageList(15) // 筛选相关状态 const selectedYear = ref('') @@ -258,6 +263,10 @@ const imageRefs = ref<(HTMLElement | null)[]>([]) const imageVisibility = ref([]) let observer: IntersectionObserver | null = null +// 无限滚动加载 +const loadMoreTrigger = ref(null) +let loadMoreObserver: IntersectionObserver | null = null + // 计算可用的年份列表(基于当前日期生成,从2020年到当前年份) const availableYears = computed(() => { const currentYear = new Date().getFullYear() @@ -360,16 +369,6 @@ const setupObserver = () => { }) } -// 初始化懒加载状态 -onMounted(() => { - // 初始化时设置 - if (images.value.length > 0) { - imageVisibility.value = new Array(images.value.length).fill(false) - setTimeout(() => { - setupObserver() - }, 100) - } -}) // 监听 images 变化,动态更新 imageVisibility watch(() => images.value.length, (newLength, oldLength) => { @@ -399,11 +398,51 @@ watch(() => images.value.length, (newLength, oldLength) => { } }) +// 设置无限滚动 Observer +const setupLoadMoreObserver = () => { + if (loadMoreObserver) { + loadMoreObserver.disconnect() + } + + loadMoreObserver = new IntersectionObserver( + (entries) => { + entries.forEach(entry => { + if (entry.isIntersecting && !loading.value && hasMore.value) { + loadMore() + } + }) + }, + { + root: null, + rootMargin: '100px', + threshold: 0.1 + } + ) + + if (loadMoreTrigger.value) { + loadMoreObserver.observe(loadMoreTrigger.value) + } +} + +// 初始化时设置无限滚动 +onMounted(() => { + if (images.value.length > 0) { + imageVisibility.value = new Array(images.value.length).fill(false) + setTimeout(() => { + setupObserver() + setupLoadMoreObserver() + }, 100) + } +}) + // 清理 onUnmounted(() => { if (observer) { observer.disconnect() } + if (loadMoreObserver) { + loadMoreObserver.disconnect() + } }) // 格式化日期 diff --git a/webapp/src/views/ImageView.vue b/webapp/src/views/ImageView.vue index 9b8588d..4419ed8 100644 --- a/webapp/src/views/ImageView.vue +++ b/webapp/src/views/ImageView.vue @@ -89,7 +89,7 @@