You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VueUse useInfiniteScroll在Vue3正常运行,为何在Nuxt3中失效?

Nuxt3中useInfiniteScroll无法触发加载的原因及解决办法

问题根源

在Nuxt3中,默认页面布局的滚动容器并非你绑定ref="el"的自定义div,而是外层的#__nuxt或#__layout容器。你的代码监听的是自定义div的滚动事件,但实际滚动发生在父容器上,导致useInfiniteScroll无法检测到滚动到底部的动作。而Vue3项目没有这种默认布局容器的层级问题,所以功能正常。

另外,你给自定义div设置的h-100类(假设使用Tailwind CSS)需要父元素也设置100%高度才能生效,否则该div不会占满视口高度,自然不会出现滚动条,滚动事件也就无从触发。

解决办法

办法1:监听window的滚动事件

直接将useInfiniteScroll的监听目标改为window,这样无论滚动容器是谁,都能正确检测滚动到底部的动作:

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

const data = ref([]);
const total = ref(0);

// 监听window的滚动
useInfiniteScroll(window, 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 class="el">
    <div v-for="item in data" class="card">
      <img :src="item.thumbnail" alt="" />
      <h3>{{ item.title }}</h3>
      <p>{{ item.description }}</p>
    </div>
  </div>
</template>

办法2:让自定义div成为滚动容器

确保自定义div成为实际的滚动容器,需要调整样式使其占满视口并开启垂直滚动:

<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-screen overflow-y-auto">
    <div v-for="item in data" class="card">
      <img :src="item.thumbnail" alt="" />
      <h3>{{ item.title }}</h3>
      <p>{{ item.description }}</p>
    </div>
  </div>
</template>

<style>
/* 确保根元素占满视口高度 */
html, body, #__nuxt, #__layout {
  height: 100%;
  margin: 0;
  padding: 0;
}
</style>

这里用h-screen替代h-100确保div占满整个视口高度,同时添加overflow-y-auto使其出现垂直滚动条,再通过全局样式让所有父容器都占满视口高度,保证自定义div成为滚动容器。

内容的提问来源于stack exchange,提问作者redshift

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 07:43:18