1

Can someone tell me why the page won't load more data when user scrolls to the bottom of the viewport? It doesn't seem to work in Nuxt3, but it works fine in Vue 3. Why?

I am using the useInfiniteScroll composable from VueUse like so in a Nuxt3 app:

<script setup lang="ts">
import { useInfiniteScroll } from '@vueuse/core';

const el = ref<HTMLElement>(null);
const data = ref([]);
const total = ref(0);

useInfiniteScroll(el, loadData, { distance: 10 });

loadData();

async function loadData() {
  if (data.value.length !== 0 && data.value.length >= total.value) return;
  const res = await fetch(
    `https://dummyjson.com/products/?limit=10&skip=${data.value.length}`
  );
  const d = await res.json();
  total.value = d.total;
  data.value = data.value.concat(d.products);
}
</script>

<template>
  <div ref="el" class="el h-100">
    <div v-for="item in data" class="card">
      <img :src="item.thumbnail" alt="" />
      <h3>{{ item.title }}</h3>
      <p>{{ item.description }}</p>
    </div>
  </div>
</template>

Here's a full Nuxt3 reproduction here: https://stackblitz.com/edit/nuxt-starter-buzm4q?file=pages/index.vue

A working Vue3 version is here: https://stackblitz.com/edit/vitejs-vite-9i25xx?file=src/App.vue

redshift
  • 4,815
  • 13
  • 75
  • 138

1 Answers1

1

There is a key difference in the code between the Nuxt app and the Vue 3 app

Nuxt app puts the ref on the div element

<div ref="el" class="el h-100">

Vue 3 app has no template ref but assigns document to the ref

onMounted(() => (el.value = document));

If you changed the Nuxt app to behave the exact same way by assigning document instead of using the template ref, you'd get the same result of a working infinite scroll.

But if the goal is to get the infinite scroll working using the template ref, you can do that by assigning a height value to the div element along with overflow: auto

body {
  margin: 0; /* remove body margin to prevent double scrollbars */
}
.el {
  height: 100vh;
  overflow: auto;
}

updated stackblitz example

yoduh
  • 7,074
  • 2
  • 11
  • 21
  • Thank you very much. Your example works, but for some reason when I copy it EXACTLY , it does not scroll on my local machine. Weird. Also, you don't have to explicitly import the `useInfiniteScroll` composable? – redshift Mar 23 '23 at 10:59
  • 1
    check for any extra margin/padding on surrounding elements that might be preventing that "bottom detection". Alternatively increasing the `distance` value might also help as 10px is a pretty small detection range. and yes, nuxt handles a lot of auto imports for you including _most_ vueuse utils once configured. The utils that can't be auto imported due to conflicts with same-named nuxt utils are listed in this [README](https://vueuse.org/nuxt/README.html) – yoduh Mar 23 '23 at 15:26