Create Infinite Scroll Load More in Laravel 9 and Vue js 3

2 years ago admin Vuejs

In this tutorial, we are going to create an infinite scroll load more in Laravel 9 and Vue js 3, the infinite scroll makes the data load on a single page as you scroll through the app.


Create the controller

I assume that you have already created a new Laravel application with Vue js already installed, and you have a database with a posts table, so the first thing we will do is to create the PostController with the method index which returns all the posts paginated.

                                                    
                                                                                                                
<?php

namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\Http\Request;

class PostController extends Controller
{
    //
    public function index(){
        $posts = Post::latest()->paginate(10);
        return response()->json($posts);
    }

}



Create the route

Next, we will add the route in the file api.php.

                                                        
                                                                                                                        
Route::get('posts',[PostController::class, 'index']);

Create the home component

In resources/js, we add new folder components inside the created folder we add a new file Home.vue in which we implement the infinite scroll load more with data retrieved from the API.

The structure of the folders:

  • resources
    • js
      • components
        • Home.vue

                                                        
                                                                                                                        
<template>
    <div class="row my-5">
        <div class="col-md-6 mx-auto">
            <div class="card my-4">
                <div class="card-body">
                    <h4 class="mb-2 border p-2 rounded">
                        All Posts
                    </h4>
                    <div class="list-group" v-for="post in data.posts.data" :key="post.id">
                        <li class="list-group-item list-group-item-action">
                            <div class="d-flex w-100 justify-content-between">
                                <h6>
                                    {{post.title}}
                                </h6>
                            </div>
                            <div class="mb-1">
                                <div>
                                    <p>
                                        {{post.body}}
                                    </p>
                                </div>
                            </div>
                        </li>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script setup>
    import { onBeforeMount, onMounted, onUnmounted, reactive } from 'vue';

    const data = reactive({
        posts: []
    });

    const fetchPosts = async () => {
        try {
            const response = await axios.get('/api/posts');
            data.posts = response.data; 
        } catch (error) {
            console.log(error);
        }
    }

    const fetchNextPosts = async () => {
        try {
            const response = await axios.get(`/api/posts?page=${data.posts.current_page += 1}`);
            response.data.data.map(item => {
                data.posts.data.push(item);
            });
        } catch (error) {
            console.log(error);
        }
    }

    const scroll = (e) => {
        if(data.posts.data.length < data.posts.total){
            let bottomOfWindow = Math.round(document.documentElement.scrollTop + window.innerHeight) === document.documentElement.offsetHeight;
            if(bottomOfWindow) {
                fetchNextPosts();
            }
        }
    };

    onMounted(() => { 
        window.addEventListener('scroll', scroll);
    });

    onBeforeMount(() => fetchPosts());

    onUnmounted(() => window.removeEventListener('scroll', scroll));
</script>

<style>
</style>

Related Tuorials

How to Persist Data in the Pinia Store

In this lesson, we will see how to persist data in the Pinia store.When working with Pinia...


How to Reset the File input Field in Vue js

In this lesson, we will see how to reset the file input field in Vue js.When uploading files using V...


Review App Using Laravel 11 & Vue js 3 Composition API Part 5

In the last part of this tutorial, we will display the reviews list of each product, add the ability...


Review App Using Laravel 11 & Vue js 3 Composition API Part 4

In the fourth part of this tutorial, we will fetch and display all the products on the home page, vi...


Review App Using Laravel 11 & Vue js 3 Composition API Part 3

In the third part of this tutorial, we will start coding the front end, first, we will install the p...


Review App Using Laravel 11 & Vue js 3 Composition API Part 2

In the second part of this tutorial, we will create the product and review controllers, and later we...


Review App Using Laravel 11 & Vue js 3 Composition API Part 1

In this tutorial, we will create a review app using Laravel 11 & Vue js 3 Composition API, the user...


Build a Shopping Cart Using Vue js 3 Composition API Laravel 11 & Stripe Payment Gateway Part 5

In the final part of this tutorial, we will display the cart items, add the ability to increment/dec...


Build a Shopping Cart Using Vue js 3 Composition API Laravel 11 & Stripe Payment Gateway Part 4

In the fourth part of this tutorial, we will fetch and display all the products, and add the store w...


Build a Shopping Cart Using Vue js 3 Composition API Laravel 11 & Stripe Payment Gateway Part 3

In the third part of this tutorial, we will move to the front end, we will install the packages...