Implementing Infinite Scroll with Laravel and Vue.js 3

Swifties Erupt in Fury After Donald Trump Uses AI to Fake Taylor Swift Endorsement


Infinite scroll is a more modern alternative to traditional pagination, providing a seamless user experience. In this blog post, we’ll implement infinite scroll in a Vue.js 3 application using Laravel as the backend.

Prerequisites

  • Basic knowledge of Laravel and Vue.js 3.
  • A Laravel project with an API to paginate data (e.g., User model).



Section 1: Setting Up the Basic Vue.js 3 Component for Infinite Scroll



Step 1: Create the Backend API

Create a simple API in your Laravel application to return paginated data:

routes/api.php

use AppModelsUser;
use IlluminateHttpRequest;

Route::get('/users', function (Request $request) {
    return User::paginate(10);
});
Enter fullscreen mode

Exit fullscreen mode



Step 2: Create the UserList Component with Infinite Scroll

Modify the UserList component to implement infinite scroll:

src/components/UserList.vue

<template>
  <div>
    <table class="table">
      <thead>
        <tr>
          <th>Name</th>
          <th>Email</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="user in users" :key="user.id">
          <td>{{ user.name }}</td>
          <td>{{ user.email }}</td>
        </tr>
      </tbody>
    </table>
    <div v-if="loading" class="loading">
      Loading more users...
    </div>
  </div>
</template>

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

export default {
  setup() {
    const users = ref([]);
    const loading = ref(false);
    let page = ref(1);
    let observer;

    const fetchUsers = async () => {
      loading.value = true;
      try {
        const response = await axios.get(`/api/users?page=${page.value}`);
        if (response.data.data.length > 0) {
          users.value.push(...response.data.data);
          page.value++;
        }
      } catch (error) {
        console.error(error);
      } finally {
        loading.value = false;
      }
    };

    const handleScroll = () => {
      const scrollableHeight = document.documentElement.scrollHeight - window.innerHeight;
      const scrolledFromTop = window.scrollY;

      if (scrollableHeight - scrolledFromTop < 100 && !loading.value) {
        fetchUsers();
      }
    };

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

    onBeforeUnmount(() => {
      window.removeEventListener('scroll', handleScroll);
    });

    return {
      users,
      loading,
    };
  },
};
</script>

<style>
.loading {
  text-align: center;
  margin-top: 10px;
}
</style>
Enter fullscreen mode

Exit fullscreen mode



Step 3: Integrate the Component in Your Vue App

Include the component in your Vue app:

src/main.js

import { createApp } from 'vue';
import App from './App.vue';
import UserList from './components/UserList.vue';

const app = createApp(App);

app.component('user-list', UserList);

app.mount('#app');
Enter fullscreen mode

Exit fullscreen mode

src/App.vue

<template>
  <div id="app">
    <user-list></user-list>
  </div>
</template>

<script>
export default {
  name: 'App',
};
</script>
Enter fullscreen mode

Exit fullscreen mode




Section 2: Managing Infinite Scroll with Vuex

If you need to manage the state of infinite scroll across different components, Vuex can help.



Step 1: Set Up Vuex Store

Create a store to manage the users and infinite scroll state:

src/store/index.js

import { createStore } from 'vuex';
import axios from 'axios';

export default createStore({
  state: {
    users: [],
    loading: false,
    page: 1,
  },
  mutations: {
    ADD_USERS(state, users) {
      state.users.push(...users);
    },
    SET_LOADING(state, loading) {
      state.loading = loading;
    },
    INCREMENT_PAGE(state) {
      state.page++;
    },
  },
  actions: {
    async fetchUsers({ commit, state }) {
      if (state.loading) return;

      commit('SET_LOADING', true);
      try {
        const response = await axios.get(`/api/users?page=${state.page}`);
        if (response.data.data.length > 0) {
          commit('ADD_USERS', response.data.data);
          commit('INCREMENT_PAGE');
        }
      } catch (error) {
        console.error(error);
      } finally {
        commit('SET_LOADING', false);
      }
    },
  },
  getters: {
    users(state) {
      return state.users;
    },
    loading(state) {
      return state.loading;
    },
  },
});
Enter fullscreen mode

Exit fullscreen mode



Step 2: Update the UserList Component

Modify the UserList component to use Vuex for managing the infinite scroll state:

src/components/UserList.vue

<template>
  <div>
    <table class="table">
      <thead>
        <tr>
          <th>Name</th>
          <th>Email</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="user in users" :key="user.id">
          <td>{{ user.name }}</td>
          <td>{{ user.email }}</td>
        </tr>
      </tbody>
    </table>
    <div v-if="loading" class="loading">
      Loading more users...
    </div>
  </div>
</template>

<script>
import { mapActions, mapGetters } from 'vuex';
import { onMounted, onBeforeUnmount } from 'vue';

export default {
  computed: {
    ...mapGetters(['users', 'loading']),
  },
  methods: {
    ...mapActions(['fetchUsers']),
    handleScroll() {
      const scrollableHeight = document.documentElement.scrollHeight - window.innerHeight;
      const scrolledFromTop = window.scrollY;

      if (scrollableHeight - scrolledFromTop < 100 && !this.loading) {
        this.fetchUsers();
      }
    },
  },
  created() {
    this.fetchUsers();
  },
  mounted() {
    window.addEventListener('scroll', this.handleScroll);
  },
  beforeUnmount() {
    window.removeEventListener('scroll', this.handleScroll);
  },
};
</script>

<style>
.loading {
  text-align: center;
  margin-top: 10px;
}
</style>
Enter fullscreen mode

Exit fullscreen mode



Step 3: Integrate Vuex into Your Vue App

Ensure that Vuex is integrated into your Vue.js application:

src/main.js

import { createApp } from 'vue';
import App from './App.vue';
import store from './store'; // Import the Vuex store
import UserList from './components/UserList.vue';

const app = createApp(App);

app.use(store); // Use Vuex store in the app
app.component('user-list', UserList);

app.mount('#app');
Enter fullscreen mode

Exit fullscreen mode



Step 4: Modify App.vue

Your main App.vue should include the UserList component:

<!-- src/App.vue -->
<template>
  <div id="app">
    <user-list></user-list>
  </div>
</template>

<script>
export default {
  name: 'App',
};
</script>
Enter fullscreen mode

Exit fullscreen mode

By following these steps, you’ve successfully implemented infinite scroll in a Vue.js 3 application, using Laravel as the backend. Whether you’re handling state locally within a component or globally with Vuex, infinite scroll provides a smooth, modern user experience. The Vuex integration is particularly useful when managing the scroll state across multiple components or views, ensuring that your application remains scalable and maintainable.

This approach not only enhances user experience by loading data dynamically as the user scrolls but also optimizes performance by loading only necessary data at a time.

Enjoy!



Source link
lol

By stp2y

Leave a Reply

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

No widgets found. Go to Widget page and add the widget in Offcanvas Sidebar Widget Area.