mirror of
https://github.com/nagisa77/OpenIsle.git
synced 2026-03-03 02:20:49 +08:00
feat(frontend): add infinite scroll for posts
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="home-page">
|
<div class="home-page" @scroll="handleScroll">
|
||||||
<div class="search-container">
|
<div class="search-container">
|
||||||
<div class="search-title">Where possible begins</div>
|
<div class="search-title">Where possible begins</div>
|
||||||
<div class="search-subtitle">希望你喜欢这里。有问题,请提问,或搜索现有帖子</div>
|
<div class="search-subtitle">希望你喜欢这里。有问题,请提问,或搜索现有帖子</div>
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="isLoadingPosts" class="loading-container">
|
<div v-if="isLoadingPosts && articles.length === 0" class="loading-container">
|
||||||
<l-hatch size="28" stroke="4" speed="3.5" color="var(--primary-color)"></l-hatch>
|
<l-hatch size="28" stroke="4" speed="3.5" color="var(--primary-color)"></l-hatch>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -73,6 +73,9 @@
|
|||||||
{{ article.time }}
|
{{ article.time }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="isLoadingPosts && articles.length > 0" class="loading-container bottom-loading">
|
||||||
|
<l-hatch size="28" stroke="4" speed="3.5" color="var(--primary-color)"></l-hatch>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -110,35 +113,53 @@ export default {
|
|||||||
const selectedTopic = ref('最新')
|
const selectedTopic = ref('最新')
|
||||||
|
|
||||||
const articles = ref([])
|
const articles = ref([])
|
||||||
|
const page = ref(0)
|
||||||
|
const pageSize = 5
|
||||||
|
const allLoaded = ref(false)
|
||||||
|
|
||||||
const fetchPosts = async () => {
|
const fetchPosts = async () => {
|
||||||
|
if (isLoadingPosts.value || allLoaded.value) return
|
||||||
try {
|
try {
|
||||||
isLoadingPosts.value = true
|
isLoadingPosts.value = true
|
||||||
const res = await fetch(`${API_BASE_URL}/api/posts`)
|
const res = await fetch(`${API_BASE_URL}/api/posts?page=${page.value}&pageSize=${pageSize}`)
|
||||||
isLoadingPosts.value = false
|
isLoadingPosts.value = false
|
||||||
if (!res.ok) return
|
if (!res.ok) return
|
||||||
const data = await res.json()
|
const data = await res.json()
|
||||||
articles.value = data.map(p => ({
|
articles.value.push(
|
||||||
id: p.id,
|
...data.map(p => ({
|
||||||
title: p.title,
|
id: p.id,
|
||||||
description: p.content,
|
title: p.title,
|
||||||
category: p.category,
|
description: p.content,
|
||||||
tags: p.tags || [],
|
category: p.category,
|
||||||
members: [],
|
tags: p.tags || [],
|
||||||
comments: (p.comments || []).length,
|
members: [],
|
||||||
views: p.views,
|
comments: (p.comments || []).length,
|
||||||
time: new Date(p.createdAt).toLocaleDateString('zh-CN', { month: 'numeric', day: 'numeric' })
|
views: p.views,
|
||||||
}))
|
time: new Date(p.createdAt).toLocaleDateString('zh-CN', { month: 'numeric', day: 'numeric' })
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
if (data.length < pageSize) {
|
||||||
|
allLoaded.value = true
|
||||||
|
} else {
|
||||||
|
page.value += 1
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleScroll = (e) => {
|
||||||
|
const el = e.target
|
||||||
|
if (el.scrollHeight - el.scrollTop <= el.clientHeight + 50) {
|
||||||
|
fetchPosts()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(fetchPosts)
|
onMounted(fetchPosts)
|
||||||
|
|
||||||
const sanitizeDescription = (text) => stripMarkdown(text)
|
const sanitizeDescription = (text) => stripMarkdown(text)
|
||||||
|
|
||||||
return { topics, selectedTopic, articles, sanitizeDescription, isLoadingPosts }
|
return { topics, selectedTopic, articles, sanitizeDescription, isLoadingPosts, handleScroll }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -185,6 +206,10 @@ export default {
|
|||||||
height: 200px;
|
height: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bottom-loading {
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
.no-posts-container {
|
.no-posts-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|||||||
Reference in New Issue
Block a user