当前位置: 首页 > 知识库问答 >
问题:

vue3 - 如何实现一个无限滚动列表,并分页加载?

艾善
2024-12-15

列表中的数据是变化的,所以在实现无限滚动的同时,也要请求新的数据,这样的无限滚动怎么实现呢?现在的开发环境是vue3的,从1滚动到最后一个后,再从1开始滚动,自动滚动,不需要滚动条!当数据不足5条的时候不需要滚动
image.png

共有3个答案

江智
2024-12-15

https://vueuse.org/core/useInfiniteScroll/#useinfinitescroll

这个符合你的要求吗?

訾旭
2024-12-15
<template>
  <div class="card-list">
    <div class="card-item" v-for="(item, index) in list">
        {{ item }}
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted } from "vue";

const rbTimer = ref(null);
const totalList = ref([
  1,
  2,
  3,
  4,
  5,
  6,
  7,
  8,
  9,
  10,
  11,
  12,
  13,
  14,
  15,
  16,
  17,
  18,
  19,
]);
const list = ref([1, 2, 3, 4, 5]);
const pageSize = 5; // 每页显示的条数
let currentPage = 1; // 当前页码

onMounted(() => {
  const cardList = document.getElementsByClassName("card-list")[0];
  if (totalList.value.length > pageSize) {
    rbTimer.value = scroll(cardList);
  }
});

const scroll = (tableDom) => {
  let isScroll = true;
  tableDom.addEventListener("mouseover", () => {
    isScroll = false;
  });
  tableDom.addEventListener("mouseout", () => {
    isScroll = true;
  });
  return setInterval(() => {
    if (isScroll) {
      tableDom.scrollTop += 3; // 设置滚动速度
      if (
        Math.abs(tableDom.clientHeight + tableDom.scrollTop - tableDom.scrollHeight) <= 2
      ) {
        if (list.value.length === totalList.value.length) {
          tableDom.scrollTop = 0;
        }
        setTimeout(loadNextPage, 500); // 延迟500毫秒加载下一页数据
      }
    }
  }, 100);
};

const loadNextPage = () => {
  if (currentPage * pageSize < totalList.value.length) {
    currentPage++;
    list.value =[...list.value, ...totalList.value.slice(
      (currentPage - 1) * pageSize,
      currentPage * pageSize
    )];
  }
};
</script>

<style>
.card-list {
  height: 100px;
  overflow-y: auto;
  overflow: scroll;
}

.card-list::-webkit-scrollbar{
  width: 0;
  height: 0;
}

.card-item{
  line-height: 40px;
}

.card-item:nth-child(odd) {
  height: 40px;
  background: #20a6ff;
}

.card-item:nth-child(even) {
  height: 40px;
  background:#19daf9;
}
</style>
蒋曾笑
2024-12-15
### 实现无限滚动列表并分页加载(Vue 3)

要在 Vue 3 中实现一个无限滚动列表并分页加载数据,同时考虑数据的变化和循环滚动,你可以按照以下步骤进行:

1. **设置基本结构**:
   - 使用 Vue 3 的组合式 API。
   - 创建一个用于存储数据的数组 `items`。
   - 创建一个当前页码 `currentPage` 和每页显示的项目数量 `pageSize`。

2. **实现滚动监听**:
   - 使用 `onMounted` 和 `onUnmounted` 生命周期钩子来添加和移除滚动事件监听器。
   - 在滚动事件处理函数中,检查是否滚动到底部,如果是,则加载更多数据。

3. **数据请求**:
   - 使用一个函数 `fetchData` 来模拟从服务器获取数据。
   - 每次滚动到底部时,调用 `fetchData` 并更新 `items` 数组。

4. **处理数据变化**:
   - 在数据加载后,合并新数据到 `items` 数组中。
   - 如果有必要,处理数据去重或更新逻辑。

5. **实现循环滚动**:
   - 在滚动到底部并加载新数据后,如果数据数量足够多,可以通过调整滚动位置来实现循环效果。
   - 例如,可以在加载新数据后,立即将滚动位置重置到顶部。

### 示例代码

<template>
<div @scroll="handleScroll" class="infinite-scroll-container" ref="scrollContainer">

<ul>
  <li v-for="item in items" :key="item.id">{{ item.name }}</li>
</ul>

</div>
</template>

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

export default {
setup() {

const items = reactive([]);
const currentPage = ref(1);
const pageSize = 10;
const scrollContainer = ref(null);

const fetchData = async (page) => {
  // 模拟从服务器获取数据
  const newData = Array.from({ length: pageSize }, (_, i) => ({
    id: (page - 1) * pageSize + i + 1,
    name: `Item ${(page - 1) * pageSize + i + 1}`,
  }));
  return newData;
};

const loadMoreData = async () => {
  const newItems = await fetchData(currentPage.value);
  items.push(...newItems);
  currentPage.value += 1;
  
  // 循环滚动:重置滚动位置到顶部
  if (scrollContainer.value) {
    scrollContainer.value.scrollTop = 0;
  }
};

const handleScroll = () => {
  const bottomOfWindow =
    scrollContainer.value.scrollHeight - scrollContainer.value.scrollTop ===
    scrollContainer.value.clientHeight;
  if (bottomOfWindow) {
    loadMoreData();
  }
};

onMounted(() => {
  // 初始加载第一页数据
  loadMoreData();
  window.addEventListener('scroll', handleScroll);
});

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

return {
  items,
  scrollContainer,
};

},
};
</script>

<style>
.infinite-scroll-container {
height: 300px; / 设置容器高度以启用滚动 /
overflow-y: auto;
border: 1px solid #ccc;
}
</style>


### 解释
- **模板部分**:使用 `v-for` 指令渲染列表项,并在 `div` 容器上监听滚动事件。
- **脚本部分**:
  - 使用 `reactive` 管理 `items` 数组。
  - 使用 `ref` 管理当前页码、每页大小和滚动容器引用。
  - `fetchData` 函数模拟数据获取。
  - `loadMoreData` 函数加载更多数据并处理循环滚动逻辑。
  - `handleScroll` 函数检查是否滚动到底部并调用 `loadMoreData`。
  - 在 `onMounted` 中初始加载数据并添加滚动事件监听器,在 `onUnmounted` 中移除监听器。
- **样式部分**:设置容器高度和滚动条样式。

这个示例提供了一个基本框架,你可以根据实际需求进行扩展和优化,比如处理数据更新、去重、错误处理等。
 类似资料:
  • 本文向大家介绍js实现列表向上无限滚动,包括了js实现列表向上无限滚动的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了js实现列表向上无限滚动的具体代码,供大家参考,具体内容如下 先来一张效果图 html js css(样式自己调) 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。

  • 本文向大家介绍基于JavaScript实现移动端无限加载分页,包括了基于JavaScript实现移动端无限加载分页的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了js实现移动端无限加载分页的具体代码,供大家参考,具体内容如下 原理:当滚动条到达底部时,执行下一页内容。 判断条件需要理解三个概念:     1.scrollHeight 真实内容的高度     2.clientHeigh

  • 本文向大家介绍基于JavaScript实现表格滚动分页,包括了基于JavaScript实现表格滚动分页的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了js实现表格滚动分页展示的具体代码,供大家参考,具体内容如下 CSS: JS: 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。

  • 问题内容: 如何使量角器向下滚动到桌子上?我的表可以无限滚动- 加载20条记录,并且在显示倒数第二行时,它将获取接下来的20条记录。并非所有记录都在视图中…有些滚动到下面,而有些滚动到用户上方时。我以为测试是 这是正确的方法吗? HTML表格代码: 问题答案: 这个想法是在表(标签)中找到最新的元素,然后通过将父元素的元素设置为最后一个元素的元素来滚动到该元素。 该属性获取或设置元素内容向上滚动的

  • 我有一个要求,我需要展示一张长桌。它不需要一次全部显示,所以ajax加载它(加载前50条记录,然后每次用户滚动到/超过最后一行的第十行时再获取50行)。 但我不确定分页和无限滚动这两种方式中哪一种更好。我希望用户在返回页面时能够跳转到最后一个滚动到的点(通过后退按钮,当然;如果无论用户何时访问页面,我都可以这样做,那就更好了!)前面的行也可见。同时,为了提高性能,我希望将ajax调用的数量限制在尽

  • 问题内容: 是否有任何可用于实现列表分页的库? 假设我有10行的空间,并且用户可以选择是否要按页面向前或向后滚动(因此+-10个项目)。这可能例如由来控制。 要构建一个类,以防止在没有足够的项目可显示时向后/向前滚动,以及自我保存用户当前在哪个页面上的状态,这可能是一项艰巨的工作。 那有什么事吗 问题答案: 我之前已经解决了。我做了一个静态的getPages方法,该方法将通用集合分解为页面列表(也

  • TL;DR:下面三个选项中,哪一个是使用Redis分页最有效的? 我正在实现一个网站,其中包含多个用户生成的帖子,这些帖子保存在关系数据库中,然后以散列的形式复制到Redis,其中包含像站点:{site_id}: post:{post_id}这样的键。 我想对Redis执行简单的分页查询,以便在Pinterest风格的界面中实现延迟加载分页(即用户向下滚动,我们向服务器发送一个Ajax请求,请求下

  • 问题内容: 我有一个页面(我们称其为1.php),它使用jQuery-ajax将2.php加载到div- box中。2.php从我的数据库中打印20条记录。当滚动时到达div框的底部时,我希望它加载接下来的20条记录。像Facebook,Twitter等,都是这样做的。 现在,我已经有了这种行为,但是仅当自己加载2.php时!但不在div框中。 我该怎么办? 提前致谢! 问题答案: 文件1.php