To reset the infinite scroll page to its initial state when the user navigates back to the page, you can leverage the beforeRouteEnter and beforeRouteLeave navigation guards provided by Vue Router. These guards allow you to execute code before entering or leaving a route, which is perfect for resetting the state of your component.
Here's how you can modify your Show.vue component to achieve this:
- Store the initial state: Save the initial state of your component when it is first loaded.
- Reset the state on route enter: Reset the component's state to the initial state when the user navigates back to the page.
Here's the updated Show.vue component:
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import AuthenticatedLayout from "@/Layouts/AuthenticatedLayout.vue";
import BookLink from "@/Components/BookLink.vue";
import BookCard from "@/Components/BookCard.vue";
import { useInfiniteScroll } from "@/Composables/useInfiniteScroll.js";
const props = defineProps({
books: Object,
errors: Object,
flash: Object,
from: Number,
nextPageUrl: String,
previousPageUrl: String,
reading_list: Object,
to: Number,
total: Number
});
const readingList = props.reading_list;
const totalBookNumber = props.total;
const initialBooks = ref(props.books);
const initialNextPageUrl = ref(props.nextPageUrl);
const { items, landmark, loadMoreItems } = useInfiniteScroll(initialBooks.value, initialNextPageUrl.value, {
itemsPropName: 'books',
nextPageUrlPropName: 'nextPageUrl'
});
const route = useRoute();
const router = useRouter();
router.beforeEach((to, from, next) => {
if (to.name === 'Show' && from.name === 'BookDetail') {
items.value = initialBooks.value;
nextPageUrl.value = initialNextPageUrl.value;
}
next();
});
onMounted(() => {
// Any additional setup if needed
});
onUnmounted(() => {
// Any cleanup if needed
});
</script>
<template>
<AuthenticatedLayout>
<div class="relative flex size-full flex-col bg-[#f8f9fc] group/design-root overflow-x-hidden min-h-screen"
style='font-family: Newsreader, "Noto Sans", sans-serif;'>
<div class="layout-container flex min-h-screen flex-col">
<div class="px-40 flex flex-1 justify-center py-5">
<div class="layout-content-container flex flex-col max-w-[960px] w-full">
<div class="flex flex-wrap justify-between gap-3 p-4">
<div class="flex min-w-72 flex-col gap-3">
<p class="text-[#0e121b] tracking-light text-[32px] font-bold leading-tight">
{{ readingList.name }}</p>
<p class="text-[#4e6597] text-sm font-normal leading-normal">By {{ readingList.user.name
}}, {{ totalBookNumber }} books</p>
</div>
</div>
<h3 class="text-[#0e121b] text-lg font-bold leading-tight tracking-[-0.015em] px-4 pb-2 pt-4">
Books ({{ totalBookNumber }})</h3>
<div class="px-4 pb-2 pt-4">
<h4>{{ readingList.description }}</h4>
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-4">
<BookLink
v-for="item in items"
:key="item.id"
:component="BookCard"
:urlLink="route('books.show', item.id)"
:imageUrl="item.url"
:name="item.title"
/>
<div ref="landmark"></div>
</div>
</div>
</div>
</div>
</div>
</AuthenticatedLayout>
</template>
Explanation:
-
Initial State: The initial state of the books and the next page URL is stored in
initialBooksandinitialNextPageUrlrespectively. -
Router Guard: The
beforeEachnavigation guard checks if the user is navigating back to theShowpage from theBookDetailpage. If so, it resets theitemsandnextPageUrlto their initial values. -
Template: The template remains mostly unchanged, but make sure to add a
keyto thev-forloop to help Vue efficiently update the DOM.
This approach ensures that when the user navigates back to the Show.vue page, the infinite scroll is reset to its initial state.