Vue Infinite Scroll

Implement an infinite scroll component using Vue and intersection observer API.

Steps

  1. Create Observer.vue component to use Intersection Observer API

    <script setup>
    import { ref, onMounted, onUnmounted } from 'vue'
    const props = defineProps({
      options: {
        type: Object,
        default: () => {},
      },
    })
    const emit = defineEmits(['intersect'])
    const root = ref(null)
    const observer = ref(null)
    onMounted(() => {
      observer.value = new IntersectionObserver(([entry]) => {
        if (entry && entry.isIntersecting) {
          emit('intersect')
        }
      }, props.options)
      observer.value.observe(root.value)
    })
    onUnmounted(() => {
      observer.value.disconnect()
    })
    </script>
    
    <template>
      <div ref="root" />
    </template>
  2. Create InfiniteScroll.vue component

    <script setup>
    import { ref } from 'vue'
    import Observer from './Observer.vue'
    
    const page = ref(1)
    const items = ref([])
    
    const getItems = async () => {
      const res = await fetch(
        `https://jsonplaceholder.typicode.com/comments?_page=${page.value}&_limit=20`
      )
      page.value++
      const data = await res.json()
      items.value = [...items.value, ...data]
    }
    </script>
    
    <template>
      <div
        class="h-[400px] w-[800px] overflow-auto border border-solid border-blue-300"
      >
        <ui class="block p-4">
          <li class="text-left" v-for="item in items" :key="item.id">
            {{ item.name }}
          </li>
        </ui>
    
        <Observer @intersect="getItems" />
      </div>
    </template>

Reference

GitHub

View Github