Infinite Scroll
This recipe demonstrates how to implement an infinite scroll pattern using pocket-vue.
Example Code
html
<div v-scope="{
items: [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' },
{ id: 3, name: 'Item 3' }
],
loading: false,
page: 1,
loadMore() {
if (this.loading) return;
this.loading = true;
setTimeout(() => {
this.page++;
const newItems = [
{ id: (this.page - 1) * 3 + 1, name: 'Item ' + ((this.page - 1) * 3 + 1) },
{ id: (this.page - 1) * 3 + 2, name: 'Item ' + ((this.page - 1) * 3 + 2) },
{ id: (this.page - 1) * 3 + 3, name: 'Item ' + ((this.page - 1) * 3 + 3) }
];
this.items = [...this.items, ...newItems];
this.loading = false;
}, 1000);
},
setupScrollListener() {
window.addEventListener('scroll', () => {
if (window.innerHeight + window.scrollY >= document.body.offsetHeight - 10) {
this.loadMore();
}
});
}
}" @vue:mounted="setupScrollListener()">
<div class="infinite-scroll">
<ul>
<li v-for="item in items" :key="item.id">
{{ item.name }}
</li>
</ul>
<p v-show="loading">Loading more items...</p>
<button v-show="!loading" @click="loadMore">Load More</button>
</div>
</div>How it works
- Reactive State: We use an
itemsarray, aloadingboolean, and apagenumber to manage our state. - Load More Logic: We provide a
loadMore()method to fetch more items from the server and append them to the current list. - Scroll Event Listener: We wire up
@vue:mounted="setupScrollListener()"to attach a scroll event listener when the component is mounted, which detects when the user reaches the bottom of the page and triggersloadMore. - Loading State: We use the
loadingproperty to show or hide a loading indicator and prevent multiple requests from being made at once. - List Rendering: We use
v-for="item in items"to render the concatenated list of items. - Optimized Rendering: By using
:key="item.id", we ensure that pocket-vue efficiently updates only the new items as they are added to the DOM. - Fallback Mechanism: We provide a "Load More" button as a fallback for users who prefer manual navigation.
