Infinite scrolling is something that we’ve to add often into our Vue 3 app.
In this article, we’ll look at how to add infinite scrolling to a Vue 3 app with the Intersection Observer API.
Add Infinite Scrolling with the Intersection Observer API
The Intersection API lets us add infinite scrolling easily in our Vue 3 app.
To do this, we assign a ref to the last element and watch when that element is displayed on the screen.
Then when the array changes, we reassign the ref to the last element that’s added then.
For instance, we can write:
<template>
<div
v-for="(a, i) of arr"
:key="a"
:ref="i === arr.length - 1 ? 'last' : undefined"
>
{{ a }}
</div>
</template>
<script>
export default {
name: "App",
data() {
return {
page: 1,
arr: Array(30)
.fill()
.map((_, i) => i),
observer: undefined,
};
},
methods: {
async addObserver() {
await this.$nextTick();
const options = {
root: document,
rootMargin: "20px",
threshold: 1,
};
const callback = (entries) => {
if (entries[0].isIntersecting) {
this.arr = [
...this.arr,
...Array(30)
.fill()
.map((_, i) => i + 30 * (this.page - 1)),
];
this.page++;
}
};
this.observer = new IntersectionObserver(callback, options);
this.observer.observe(this.$refs.last);
},
},
mounted() {
this.addObserver();
},
watch: {
arr: {
deep: true,
handler() {
this.addObserver();
},
},
},
};
</script>
We have a series of divs rendered from the arr
array in the component template.
The ref
prop is set by checking whether the index of the item is the same as arr.length — 1
.
If it is, then it’s the last item, so we assign a ref to that.
Otherwise, we don’t assign a ref to it.
The data
method returns the page
number and the arr
array with the data to render.
In the methods
object, we have the addObserver
methgod to add the Intersection Observer and use that to watch when the element that we assigned the ref to appears on the screen.
To do this, we call $nextTick
to make sure the elements are rendered.
Then we set the options for detecting intersection.
root
is the element that has the items we watch for.
rootMargin
is the margin to determine when the item is considered to be on the screen.
threshold
is the threshold for the element to be displayed. It’s the portion of the element that’s appeared on the screen. And it’s a number between 0 and 1.
Next, we have the callback
function that checks the isIntersecting
property to see if the last element appeared.
If it has, then we update the arr
array by putting more entries in it.
We also update the page
value.
Next, we create the IntersectionObserver
instance with the callback
and options
.
Then we call observe
on it with the element that’s been assigned the ref to watch it appear on the screen.
We call this method with the component is mounted and when the arr
array changes.
The mounted
hook runs after the component is rendered, so we can get the element with the ref assigned and watch it appear on the screen.
Now when we scroll down, we should see more items appear.
Conclusion
We can use the Intersection Observer API easily to add infinite scrolling easily into our Vue 3 app.