feat: home topic lazy load
This commit is contained in:
parent
f086fabc03
commit
d8e57311f5
|
@ -33,6 +33,8 @@ onBeforeMount(() => {
|
|||
|
||||
// 定义防抖处理函数
|
||||
const debouncedSearch = debounce((inputValue: string) => {
|
||||
// 搜索之前重置页数,是否加载等页面状态
|
||||
useKUNGalgameHomeStore().resetPageStatus()
|
||||
keywords.value = inputValue
|
||||
}, 300) // 300 毫秒的防抖延迟
|
||||
|
||||
|
|
|
@ -12,6 +12,8 @@ interface HomeStore {
|
|||
limit: number
|
||||
sortField: string
|
||||
sortOrder: string
|
||||
// 加载完了是否还需要加载
|
||||
isLoading: boolean
|
||||
|
||||
// 其它的 store
|
||||
// 是否激活主页的左侧交互面板
|
||||
|
@ -41,6 +43,7 @@ export const useKUNGalgameHomeStore = defineStore({
|
|||
limit: 17,
|
||||
sortField: 'updated',
|
||||
sortOrder: 'desc',
|
||||
isLoading: true,
|
||||
|
||||
// 其它的 store
|
||||
// 是否激活主页的左侧交互面板
|
||||
|
@ -57,8 +60,8 @@ export const useKUNGalgameHomeStore = defineStore({
|
|||
const requestData: HomeTopicRequestData = {
|
||||
keywords: this.keywords,
|
||||
category: this.category,
|
||||
page: this.page || 1,
|
||||
limit: this.limit || 17,
|
||||
page: this.page,
|
||||
limit: this.limit,
|
||||
sortField: this.sortField || 'updated',
|
||||
sortOrder: this.sortOrder || 'desc',
|
||||
}
|
||||
|
@ -72,5 +75,10 @@ export const useKUNGalgameHomeStore = defineStore({
|
|||
})
|
||||
})
|
||||
},
|
||||
// 重置页数,是否加载,这样排序才能生效
|
||||
resetPageStatus() {
|
||||
this.page = 1
|
||||
this.isLoading = true
|
||||
},
|
||||
},
|
||||
})
|
||||
|
|
|
@ -57,6 +57,8 @@ interface Topic {
|
|||
isShowAdvance: boolean
|
||||
// 是否激活左侧交互面板
|
||||
isActiveAside: boolean
|
||||
// 是否滚动到顶部
|
||||
isScrollToTop: boolean
|
||||
|
||||
// 回复的缓存
|
||||
replyDraft: ReplyDraft
|
||||
|
@ -74,6 +76,7 @@ export const useKUNGalgameTopicStore = defineStore({
|
|||
isEdit: false,
|
||||
isShowAdvance: false,
|
||||
isActiveAside: false,
|
||||
isScrollToTop: false,
|
||||
replyDraft: {
|
||||
tid: 0,
|
||||
r_uid: 0,
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue'
|
||||
import {
|
||||
ref,
|
||||
watch,
|
||||
onMounted,
|
||||
onBeforeUnmount,
|
||||
onBeforeMount,
|
||||
nextTick,
|
||||
} from 'vue'
|
||||
import SingleTopic from './SingleTopic.vue'
|
||||
|
||||
import { HomeTopic } from '@/api/index'
|
||||
|
@ -8,23 +15,82 @@ import { HomeTopic } from '@/api/index'
|
|||
import { useKUNGalgameHomeStore } from '@/store/modules/home'
|
||||
import { storeToRefs } from 'pinia'
|
||||
|
||||
const requestData = storeToRefs(useKUNGalgameHomeStore())
|
||||
const { page, keywords, sortField, sortOrder, isLoading } = storeToRefs(
|
||||
useKUNGalgameHomeStore()
|
||||
)
|
||||
|
||||
// 在组件中定义响应式的话题数据
|
||||
const topics = ref<HomeTopic[]>([])
|
||||
// 页面的容器,用于计算是否到达底部
|
||||
const content = ref<HTMLElement>()
|
||||
|
||||
// 调用 fetchTopics 获取话题数据(watch 大法好!)
|
||||
watch(
|
||||
[requestData.keywords, requestData.sortField, requestData.sortOrder],
|
||||
async () => {
|
||||
topics.value = (await useKUNGalgameHomeStore().getHomeTopic()).data
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
watch([keywords, sortField, sortOrder], async () => {
|
||||
topics.value = (await useKUNGalgameHomeStore().getHomeTopic()).data
|
||||
})
|
||||
|
||||
// 滚动事件处理函数
|
||||
const scrollHandler = async () => {
|
||||
// 滚动到底部的处理逻辑
|
||||
if (isScrollAtBottom() && isLoading.value) {
|
||||
// 自动增加页数
|
||||
page.value++
|
||||
|
||||
const lazyLoadTopics = (await useKUNGalgameHomeStore().getHomeTopic()).data
|
||||
|
||||
// 判断是否已经将数据加载完,加载完则不需要加载了
|
||||
if (!lazyLoadTopics.length) {
|
||||
isLoading.value = false
|
||||
}
|
||||
|
||||
// 将新加载的回复数据追加到已有的回复数据中
|
||||
topics.value = [...topics.value, ...lazyLoadTopics]
|
||||
}
|
||||
}
|
||||
|
||||
// 判断是否滚动到底部
|
||||
const isScrollAtBottom = () => {
|
||||
if (content.value) {
|
||||
const scrollHeight = content.value.scrollHeight
|
||||
const scrollTop = content.value.scrollTop
|
||||
const clientHeight = content.value.clientHeight
|
||||
|
||||
// 使用误差范围来比较,因为 js 浮点数不精确
|
||||
// 为什么是 1007 呢,因为我抽到鲲是在 10 月 7 日,啊哈哈哈
|
||||
const errorMargin = 1.007
|
||||
return Math.abs(scrollHeight - scrollTop - clientHeight) < errorMargin
|
||||
}
|
||||
}
|
||||
|
||||
onBeforeMount(async () => {
|
||||
// 挂载之前重置页数,是否加载等页面状态
|
||||
useKUNGalgameHomeStore().resetPageStatus()
|
||||
})
|
||||
|
||||
// 在组件挂载后,添加滚动事件监听器
|
||||
onMounted(async () => {
|
||||
// 获取滚动元素的引用
|
||||
const element = content.value
|
||||
|
||||
if (element) {
|
||||
element.addEventListener('scroll', scrollHandler)
|
||||
}
|
||||
|
||||
topics.value = (await useKUNGalgameHomeStore().getHomeTopic()).data
|
||||
})
|
||||
|
||||
// 在组件卸载前,移除滚动事件监听器
|
||||
onBeforeUnmount(() => {
|
||||
const element = content.value
|
||||
|
||||
if (element) {
|
||||
element.removeEventListener('scroll', scrollHandler)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="topic-container">
|
||||
<div class="topic-container" ref="content">
|
||||
<TransitionGroup name="list" tag="div">
|
||||
<!-- 该状态为 2 则话题处于被推状态 -->
|
||||
<div
|
||||
|
|
|
@ -7,18 +7,21 @@ import { storeToRefs } from 'pinia'
|
|||
// 导入排序列表的字段
|
||||
import { navSortItem } from './navSortItem'
|
||||
|
||||
const homeStore = storeToRefs(useKUNGalgameHomeStore())
|
||||
const { sortField, sortOrder } = storeToRefs(useKUNGalgameHomeStore())
|
||||
|
||||
const handleSortByField = (sortField: string) => {
|
||||
homeStore.sortField.value = sortField
|
||||
const handleSortByField = (field: string) => {
|
||||
useKUNGalgameHomeStore().resetPageStatus()
|
||||
sortField.value = field
|
||||
}
|
||||
|
||||
const orderAscending = () => {
|
||||
homeStore.sortOrder.value = 'asc'
|
||||
useKUNGalgameHomeStore().resetPageStatus()
|
||||
sortOrder.value = 'asc'
|
||||
}
|
||||
|
||||
const orderDescending = () => {
|
||||
homeStore.sortOrder.value = 'desc'
|
||||
useKUNGalgameHomeStore().resetPageStatus()
|
||||
sortOrder.value = 'desc'
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -33,14 +33,9 @@ import { storeToRefs } from 'pinia'
|
|||
// 当前的路由
|
||||
const route = useRoute()
|
||||
|
||||
// 使用设置面板的 store
|
||||
const settingsStore = useKUNGalgameSettingsStore()
|
||||
// 使用话题页面的 store
|
||||
const topicStore = useKUNGalgameTopicStore()
|
||||
|
||||
const { showKUNGalgamePageWidth } = storeToRefs(settingsStore)
|
||||
const { isShowAdvance, isEdit, replyDraft, replyRequest } =
|
||||
storeToRefs(topicStore)
|
||||
const { showKUNGalgamePageWidth } = storeToRefs(useKUNGalgameSettingsStore())
|
||||
const { isShowAdvance, isEdit, replyDraft, replyRequest, isScrollToTop } =
|
||||
storeToRefs(useKUNGalgameTopicStore())
|
||||
|
||||
const tid = computed(() => {
|
||||
return Number(route.params.tid)
|
||||
|
@ -82,6 +77,19 @@ watch(
|
|||
{ immediate: true }
|
||||
)
|
||||
|
||||
// 监视是否滚动到顶部
|
||||
watch(isScrollToTop, () => {
|
||||
if (content.value) {
|
||||
// 将页面滚动到顶部
|
||||
content.value.scrollTo({
|
||||
top: 0,
|
||||
behavior: 'smooth',
|
||||
})
|
||||
// 讲滚动值还原
|
||||
isScrollToTop.value = false
|
||||
}
|
||||
})
|
||||
|
||||
// 滚动事件处理函数
|
||||
const scrollHandler = async () => {
|
||||
// 滚动到底部的处理逻辑
|
||||
|
@ -112,7 +120,9 @@ const isScrollAtBottom = () => {
|
|||
const scrollTop = content.value.scrollTop
|
||||
const clientHeight = content.value.clientHeight
|
||||
|
||||
return scrollHeight - scrollTop === clientHeight
|
||||
// 使用误差范围来比较,因为 js 浮点数不精确
|
||||
const errorMargin = 1.007
|
||||
return Math.abs(scrollHeight - scrollTop - clientHeight) < errorMargin
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,6 +144,7 @@ onBeforeUnmount(() => {
|
|||
element.removeEventListener('scroll', scrollHandler)
|
||||
}
|
||||
})
|
||||
|
||||
/* 话题界面的页面宽度 */
|
||||
const topicPageWidth = computed(() => {
|
||||
return showKUNGalgamePageWidth.value.Topic + '%'
|
||||
|
@ -145,10 +156,12 @@ const resetPanelStatus = () => {
|
|||
isEdit.value = false
|
||||
}
|
||||
|
||||
// 页面离开时关闭回复面板
|
||||
onBeforeRouteLeave(() => {
|
||||
resetPanelStatus()
|
||||
})
|
||||
|
||||
// 取消挂载时关闭回复面板
|
||||
onBeforeMount(() => {
|
||||
resetPanelStatus()
|
||||
})
|
||||
|
|
|
@ -7,7 +7,7 @@ import { asideNavItem } from './asideNavItem'
|
|||
import { useKUNGalgameTopicStore } from '@/store/modules/topic'
|
||||
import { storeToRefs } from 'pinia'
|
||||
|
||||
const { replyRequest } = storeToRefs(useKUNGalgameTopicStore())
|
||||
const { isScrollToTop, replyRequest } = storeToRefs(useKUNGalgameTopicStore())
|
||||
|
||||
// 排序
|
||||
const handleSortReply = (sortField: string) => {
|
||||
|
@ -26,11 +26,7 @@ const orderDescending = () => {
|
|||
|
||||
// 回到顶端
|
||||
const handleBackToTop = () => {
|
||||
// 使用 window.scrollTo 方法将页面滚动到顶部
|
||||
window.scrollTo({
|
||||
top: 0, // 滚动到顶部的位置
|
||||
behavior: 'smooth', // 平滑滚动效果
|
||||
})
|
||||
isScrollToTop.value = true
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import { asideNavItem } from './asideNavItem'
|
|||
import { useKUNGalgameTopicStore } from '@/store/modules/topic'
|
||||
import { storeToRefs } from 'pinia'
|
||||
|
||||
const { replyRequest } = storeToRefs(useKUNGalgameTopicStore())
|
||||
const { isScrollToTop, replyRequest } = storeToRefs(useKUNGalgameTopicStore())
|
||||
|
||||
const handleSortReply = (sortField: string) => {
|
||||
replyRequest.value.sortField = sortField
|
||||
|
@ -24,11 +24,7 @@ const orderDescending = () => {
|
|||
}
|
||||
|
||||
const handleBackToTop = () => {
|
||||
// 使用 window.scrollTo 方法将页面滚动到顶部
|
||||
window.scrollTo({
|
||||
top: 0, // 滚动到顶部的位置
|
||||
behavior: 'smooth', // 平滑滚动效果
|
||||
})
|
||||
isScrollToTop.value = true
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
Loading…
Reference in a new issue