Infinite scroll is a slick UX pattern that loads content as users scroll—think Instagram or Twitter feeds. In this guide, we’ll implement infinite scroll using Vue 3’s Composition API with the new <script setup> syntax, ref, watch, and onMounted. No need for external libraries—just Vue and Axios.

image

🚀 What You’ll Learn

  • How to use <script setup> in Vue 3
  • Fetch paginated data using Axios
  • Detect when the user scrolls near the bottom
  • Load more content automatically

📦 Prerequisites

  • Basic knowledge of Vue 3
  • Vue project set up with Vite or Vue CLI
  • Axios installed (npm install axios)

💡 Setup the Component

<template>
  <div ref="scrollContainer" class="scroll-container" @scroll="handleScroll">
    <div v-for="student in students" :key="student.id" class="student-card">
      {{ student.name }}
    </div>
    <div v-if="loading" class="loader">Loading...</div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import axios from 'axios'

const students = ref([])
const page = ref(1)
const loading = ref(false)
const scrollContainer = ref(null)
const perPage = 10

const fetchStudents = async () => {
  loading.value = true
  try {
    const response = await axios.get(`/api/students?page=${page.value}&limit=${perPage}`)
    students.value.push(...response.data.students)

    if (response.data.students.length === perPage) {
      page.value++
    }
  } catch (error) {
    console.error('Error fetching students:', error)
  } finally {
    loading.value = false
  }
}

const handleScroll = () => {
  const container = scrollContainer.value
  if (!container) return

  const scrollBottom = container.scrollTop + container.clientHeight
  const threshold = container.scrollHeight - 100

  if (scrollBottom >= threshold && !loading.value) {
    fetchStudents()
  }
}

onMounted(() => {
  fetchStudents()
})
</script>

<style scoped>
.scroll-container {
  height: 500px;
  overflow-y: auto;
  padding: 16px;
  border: 1px solid #ccc;
}

.student-card {
  padding: 12px;
  margin-bottom: 10px;
  background-color: #f7f7f7;
  border-radius: 6px;
}

.loader {
  text-align: center;
  padding: 20px;
  color: #888;
}
</style>

🧠 Key Takeaways

  • We use ref to keep track of reactive variables like the page, loading state, and container reference.
  • onMounted loads the first batch of students.
  • We manually detect scroll position and trigger fetchStudents() when nearing the bottom.
  • This keeps your app lean and performant—no extra packages!

⚙️ Bonus: Backend Pagination Sample (Laravel)

If your API is Laravel-based, make sure your controller returns paginated results like this:

public function index(Request $request)
{
    $limit = $request->get('limit', 10);

    $students = Student::paginate($limit);

    return response()->json([
        'students' => $students->items(),
        'total' => $students->total(),
    ]);
}

🔚 Conclusion

With just Vue 3 core features, you can create a smooth infinite scroll experience. This not only enhances UX but also keeps your frontend performance optimized.

Want this infinite scroll in your next web app? Contact me at developerdalpat@gmail.com or Portfolio and let’s build something amazing together 🚀

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top