I’m a Vue developer and I use @tanstack/vue-query to fetch data. I have a page with cards wrapped in router-link and infinite scrolling.
The problem is when I scroll many times, go to a card (navigate to another page), and then come back I don’t return to the same scroll position.
I searched online and asked AI but most solutions say to save the position in localStorage. I don’t think this is a good way.
Do you have any idea how to solve this? Here is my code:
<TransitionGroup
v-else
name="fade"
tag="div"
class="w-full flex flex-col gap-y-3"
>
<Card
v-for="data in allData"
:key="data.id.toString()"
:data="data"
/>
<div ref="sentinel" class="h-4"></div>
</TransitionGroup>
const fetchPosts = async ({ pageParam = 1 }) => {
const response = await getDataAPI({
page: pageParam,
startDate: startDate.value ? new Date(startDate.value) : undefined,
endDate: endDate.value ? new Date(endDate.value) : undefined,
sort: sortOrder.value ? 'createdAt' : undefined,
order: sortOrder.value ? sortOrder.value : undefined,
tags: tags.value ? tags.value : undefined,
})
return response
}
const queryKey = computed(()=>([
'posts',
sortOrder.value,
startDate.value,
endDate.value,
tags.value,
]))
const {
data,
fetchNextPage,
isLoading,
hasNextPage,
isFetching,
error,
isError,
isSuccess,
} = useInfiniteQuery({
refetchOnWindowFocus: false,
refetchOnMount: true,
refetchOnReconnect: false,
queryKey: queryKey,
queryFn: fetchPosts,
getNextPageParam: (lastPage, pages) => {
const { count } = lastPage
const totalFetched = pages.reduce((acc, page) => acc + page.data.length, 0)
if (totalFetched < count) {
return pages.length + 1
}
return undefined
},
})
const allData = computed(() => {
return data.value.pages.flatMap((page) => page.data)
})
const sentinel = ref(null)
const observer = new IntersectionObserver(
(entries) => {
if (entries[0].isIntersecting && hasNextPage.value) {
fetchNextPage()
}
},
{
rootMargin: '0px 0px 0px 0px',
},
)
Card component like this:
<template>
<router-link
class="p-0.5 transition-all duration-300 ease-in-out transform hover:scale-[1.02]"
:to="{ name: 'posts' , params: { id: data.slug } ,query : $route.query }"
>
// more things
</router-link>
</template>