Implement infinite scrolling in Vue 3
useIntersectionObserver
Idea inspired byinfinite scrolling in vue. In this example, we simplify the implementation by using vueuse intersection observer hook.
Demo
scroll inside this container
item 0
item 1
item 2
item 3
item 4
item 5
item 6
item 7
item 8
item 9
Last item / you saw me
intersect: false scroll position: 0
<div ref="scrollContainer">
.
.
<div ref="targetEl">now u see me</div>
</div>
<script setup lang='ts'>
import { useIntersectionObserver } from '@vueuse/core'
const items = [...Array(10).keys()]
const fakeData = [...Array(5).keys()]
// get element reference
const targetEl = ref<HTMLElement | null>(null)
const scrollContainer = ref<HTMLElement | null>(null)
const targetIsVisible = ref(false)
const text = ref('Last item / you saw me')
// useIntersectionObserver
useIntersectionObserver(
targetEl, 👈
([{ isIntersecting }]) => {
targetIsVisible.value = isIntersecting
}
)
// watchEffect return a stop handler
const stopWatchInifiteScroll = watchEffect(() => {
if (targetIsVisible.value) {
loading.value = true
// scenario: fetch more data
setTimeout(() => {
items.value.push(...fakedata)
loading.value = false
// when loaded, scroll up a bit
// to keep the user in the same scroll position
scrollContainer.value!.scrollBy(0, -100)
}, 1000)
}
})
// condition to stop the watcher
watchEffect(() => {
if (items.value.length > 60) {
stopWatchInifiteScroll()
text.value = 'stop, that\'s a lot of calls'
}
})
This is a very straightforward implementation. The only thing to note is that we need to use theuseIntersectionObserver
hook to watch the visibility of the target element. Also, you can useuseScroll
to watch the scroll position when it reaches the bottom.
Happy Wednesday!💖
Made with❤by leovoon