Lazy loading of data during scrolling based on Vue2

insert image description here

The following is the process of implementing scrolling lazy loading:
1. An array datais defined in the object itemsto store the loaded item, loadingstatus, current page number page, number of pages per page pageSize, and the threshold from the bottom threshold.
2. In mountedthe hook function, load the data call loadMoremethod for the first time, and bind the scrolling event.
3. loadMoreAfter the method is called, loadingset the state trueto simulate asynchronous loading of data, add a fixed amount to itemsthe array , and then set the state to add 1. 4. The method monitors scrolling events to obtain the current scrolling position , viewport height , and total document height . If the document is smaller than the threshold , trigger the method to load more data. 5. The hook function unbinds the scroll event.pushitemloadingfalsepage
handleScrollscrollTopwindowHeightscrollHeight总高度 - (滚动位置 + 视口高度)thresholdloadMore
beforeDestroy

The following code loadMore()can modify the function to a real http request, and the following code uses settimeoutsimulation to generate data

<template>
  <div style="height: 100px">
    <div v-for="item in items" :key="item.id" class="item">{
    
    {
    
     item.text }}</div>
    <div v-if="loading">Loading...</div>
  </div>
</template>

<script>
import {
    
     throttle } from 'lodash'
export default {
    
    
  data() {
    
    
    return {
    
    
      items: [], // 用于存放已加载的 item
      loading: false, // 控制是否展示 loading
      page: 1, // 当前页数
      pageSize: 5, // 每页数量
      threshold: 100, // 距离底部多少像素时触发加载
    };
  },
  mounted() {
    
    
    this.loadMore(); // 首次加载数据
    window.addEventListener("scroll", throttle(this.handleScroll, 1000)); // 绑定滚动事件
  },
  methods: {
    
    
    loadMore() {
    
    
      this.loading = true; // 开启 loading 状态
      // 模拟异步加载数据
      setTimeout(() => {
    
    
        for (let i = 0; i < this.pageSize; i++) {
    
    
          this.items.push({
    
    
            id: this.items.length + 1,
            text: `Item ${
      
      this.items.length + 1}`,
          });
        }
        this.loading = false; // 关闭 loading 状态
        this.page++;
      }, 1000);
    },
    handleScroll() {
    
    
      const scrollTop =
        document.documentElement.scrollTop || document.body.scrollTop; // 获取当前滚动位置
      const windowHeight = window.innerHeight; // 获取视口高度
      const scrollHeight =
        document.documentElement.scrollHeight || document.body.scrollHeight; // 获取文档总高度
      if (scrollHeight - (scrollTop + windowHeight) < this.threshold) {
    
    
        // 判断是否已滚动到底部
        this.loadMore(); // 触发加载更多
      }
    },
  },
  beforeDestroy() {
    
    
    window.removeEventListener("scroll", throttle(this.handleScroll, 1000)); // 解绑滚动事件
  },
};
</script>
<style lang="less" scoped>
.item {
    
    
  height: 200px;
}
</style>

scrollTopIndicates the current position of the scroll bar, that is, the height that has been scrolled.
window.innerHeightIndicates the height of the browser viewport.
scrollHeightIndicates the total height of the current document, including the parts not displayed.

Guess you like

Origin blog.csdn.net/weixin_43811753/article/details/130219370