首页
Preview

Vue3 实现滚动加载更多

简介

随着移动设备的普及,滚动加载更多已经成为了一个常见的交互方式,用户可以在滚动页面时自动加载更多的数据,这种方式避免了翻页和点击“加载更多”按钮的繁琐操作,提高了用户体验。

本文将介绍如何使用 Vue3 实现滚动加载更多功能,同时提供 mock 数据,方便读者在本地调试。

准备工作

在开始之前,我们需要安装 Vue3 和 Axios,可以使用以下命令进行安装:

npm install vue@next axios

创建组件

我们将创建一个名为 InfiniteScroll 的组件,该组件将显示一些数据,并在滚动到底部时自动加载更多数据。

首先,我们需要引入 defineComponentref 函数:

import { defineComponent, ref } from 'vue'

然后,我们需要定义一些数据和方法,包括当前的页码、每页显示的数量、数据列表和是否正在加载:

export default defineComponent({
  setup() {
    const currentPage = ref(1) // 当前页码
    const pageSize = 10 // 每页数量
    const list = ref([]) // 数据列表
    const loading = ref(false) // 是否正在加载

    const loadData = () => {
      // 加载数据
    }

    return {
      currentPage,
      pageSize,
      list,
      loading,
      loadData
    }
  }
})

接下来,我们需要在组件的模板中显示数据,并监听滚动事件:

<template>
  <div class="infinite-scroll">
    <ul>
      <li v-for="item in list" :key="item.id">{{ item.title }}</li>
    </ul>
    <div v-if="loading">正在加载中...</div>
  </div>
</template>

<script>
import { defineComponent, ref } from 'vue'

export default defineComponent({
  setup() {
    const currentPage = ref(1)
    const pageSize = 10
    const list = ref([])
    const loading = ref(false)

    const loadData = () => {
      // 加载数据
    }

    const handleScroll = () => {
      // 监听滚动事件
    }

    return {
      currentPage,
      pageSize,
      list,
      loading,
      loadData,
      handleScroll
    }
  }
})
</script>

handleScroll 方法中,我们需要判断是否滚动到了底部,如果滚动到了底部,就调用 loadData 方法加载更多数据。

加载数据

loadData 方法中,我们需要使用 Axios 发送请求获取数据,并将数据添加到列表中。

为了方便调试,我们提供了一个 mock 接口,可以使用以下代码获取数据:

const loadData = async () => {
  loading.value = true // 开始加载数据
  const response = await axios.get(`https://jsonplaceholder.typicode.com/posts?_page=${currentPage.value}&_limit=${pageSize}`)
  list.value = [...list.value, ...response.data] // 将数据添加到列表中
  currentPage.value++ // 增加页码
  loading.value = false // 加载完成
}

监听滚动事件

handleScroll 方法中,我们需要获取滚动容器的高度和滚动高度,以及内容的高度,然后判断是否滚动到了底部。

const handleScroll = () => {
  const container = document.querySelector('.infinite-scroll') // 获取滚动容器
  const { scrollTop, scrollHeight, clientHeight } = container // 获取滚动高度和内容高度
  if (scrollTop + clientHeight >= scrollHeight && !loading.value) {
    loadData() // 滚动到底部,加载更多数据
  }
}

最后,我们需要在组件的 mounted 生命周期中添加滚动事件监听器:

export default defineComponent({
  setup() {
    // ...

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

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

    return {
      // ...
    }
  }
})

完整代码

<template>
  <div class="infinite-scroll">
    <ul>
      <li v-for="item in list" :key="item.id">{{ item.title }}</li>
    </ul>
    <div v-if="loading">正在加载中...</div>
  </div>
</template>

<script>
import { defineComponent, ref, onMounted, onUnmounted } from 'vue'
import axios from 'axios'

export default defineComponent({
  setup() {
    const currentPage = ref(1)
    const pageSize = 10
    const list = ref([])
    const loading = ref(false)

    const loadData = async () => {
      loading.value = true
      const response = await axios.get(`https://jsonplaceholder.typicode.com/posts?_page=${currentPage.value}&_limit=${pageSize}`)
      list.value = [...list.value, ...response.data]
      currentPage.value++
      loading.value = false
    }

    const handleScroll = () => {
      const container = document.querySelector('.infinite-scroll')
      const { scrollTop, scrollHeight, clientHeight } = container
      if (scrollTop + clientHeight >= scrollHeight && !loading.value) {
        loadData()
      }
    }

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

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

    return {
      currentPage,
      pageSize,
      list,
      loading,
      loadData
    }
  }
})
</script>

结语

本文介绍了如何使用 Vue3 实现滚动加载更多功能,包括创建组件、加载数据和监听滚动事件等。希望本文能够帮助读者更好地理解 Vue3 中的 setup 语法糖,并在实际项目中应用。

版权声明:本文内容由TeHub注册用户自发贡献,版权归原作者所有,TeHub社区不拥有其著作权,亦不承担相应法律责任。 如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

点赞(0)
收藏(0)
andrew
山重水复疑无路,柳暗花明又一坑。

评论(0)

添加评论