TorrentCardListView.vue

显示性能优化,默认只显示前面20个,页面滚到底部才会再加载新的数据。
This commit is contained in:
falling
2024-06-17 09:53:58 +08:00
parent 118a9a2c5d
commit bbf2814285
+41 -8
View File
@@ -2,6 +2,7 @@
import _ from 'lodash' import _ from 'lodash'
import type { Context } from '@/api/types' import type { Context } from '@/api/types'
import TorrentCard from '@/components/cards/TorrentCard.vue' import TorrentCard from '@/components/cards/TorrentCard.vue'
import { debounce } from 'lodash'
interface SearchTorrent extends Context { interface SearchTorrent extends Context {
more?: Array<Context> more?: Array<Context>
@@ -46,8 +47,10 @@ const editionFilterOptions = ref<Array<string>>([])
// 获取分辨率过滤选项 // 获取分辨率过滤选项
const resolutionFilterOptions = ref<Array<string>>([]) const resolutionFilterOptions = ref<Array<string>>([])
// 数据列表 // 完整的数据列表
const dataList = ref<Array<SearchTorrent>>([]) let dataList: SearchTorrent[]
// 显示用的数据列表
const displayDataList = ref<Array<SearchTorrent>>([])
// 分组后的数据列表 // 分组后的数据列表
const groupedDataList = ref<Map<string, Context[]>>() const groupedDataList = ref<Map<string, Context[]>>()
@@ -123,12 +126,20 @@ onMounted(() => {
} }
}) })
groupedDataList.value = groupMap groupedDataList.value = groupMap
window.addEventListener('scroll', handleScroll)
}) })
// 计算过滤后的列表 onBeforeUnmount(() => {
watchEffect(() => { window.removeEventListener('scroll', handleScroll)
})
// 只监听filterForm和groupedDataList的变化。因为displayDataList的变化不需要清空列表
watch([filterForm,groupedDataList], filterData)
function filterData(){
// 清空列表 // 清空列表
dataList.value = [] dataList = []
displayDataList.value = []
// 匹配过滤函数,filter中有任一值包含value则返回true // 匹配过滤函数,filter中有任一值包含value则返回true
const match = (filter: Array<string>, value: string | undefined) => const match = (filter: Array<string>, value: string | undefined) =>
filter.length === 0 || (value && filter.includes(value)) filter.length === 0 || (value && filter.includes(value))
@@ -159,11 +170,33 @@ watchEffect(() => {
const firstData = _.cloneDeepWith(matchData[0]) as SearchTorrent const firstData = _.cloneDeepWith(matchData[0]) as SearchTorrent
if (matchData.length > 1) firstData.more = matchData.slice(1) if (matchData.length > 1) firstData.more = matchData.slice(1)
dataList.value.push(firstData) // 显示前20个,4行左右。
if (displayDataList.value.length < 20) {
displayDataList.value.push(firstData)
} else {
// 后续内容不显示,存在list里。loadMore的时候再加载。
dataList.push(firstData)
}
} }
} }
}) })
}) }
//滚到底部时,加载新的数据。
const handleScroll = debounce(() => {
const bottomOffset = 50 // 距离底部多少像素开始加载
const scrollTop = window.scrollY
const windowHeight = window.innerHeight
const documentHeight = document.documentElement.scrollHeight
if (scrollTop + windowHeight + bottomOffset >= documentHeight) {
loadMore()
}
}, 100)
function loadMore() {
const itemsToMove = dataList.splice(0, 20); // 从 dataList 中获取最前面的 20 个元素
displayDataList.value.push(...itemsToMove);
}
</script> </script>
<template> <template>
@@ -249,7 +282,7 @@ watchEffect(() => {
</VRow> </VRow>
</VCard> </VCard>
<div class="grid gap-3 grid-torrent-card items-start"> <div class="grid gap-3 grid-torrent-card items-start">
<div v-for="(item) in dataList" :key="`${item.torrent_info.page_url}`"> <div v-for="(item) in displayDataList" :key="`${item.torrent_info.page_url}`">
<TorrentCard :torrent="item" :more="item.more" /> <TorrentCard :torrent="item" :more="item.more" />
</div> </div>
</div> </div>