当前位置: 首页 > news >正文

长列表局部渲染(监听window滚动),wndonw滚动同理

场景

后端一股脑给了几千个数据,我们滚动过程永远只渲染20条

原理

滚动到底时候获取裁剪位置,的到需要渲染的20条数据,通过vue diff算法更新到dom

代码

<template>
  <div class="container" @scroll="handleScroll">
    <div v-if="showRefreshHint" class="refresh-hint">下拉刷新...</div>
    <ul>
      <li v-for="(item, index) in visibleItems" :key="index" class="item">
        {{ item }}
      </li>
    </ul>
    <div v-if="loadingMore" class="loading">加载中...</div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      longArray: Array.from({ length: 1000 }, (_, i) => `Item ${i + 1}`), // 长数组
      visibleCount: 20, // 当前可见的条目数
      loadingMore: false, // 是否正在加载更多
      showRefreshHint: false, // 是否显示刷新提示
      lastScrollTop: 0, // 上一次的滚动位置
    };
  },
  computed: {
    visibleItems() {
      return this.longArray.slice(0, this.visibleCount);
    },
  },
  methods: {
    handleScroll(event) {
      const container = event.target;
      const { scrollTop, scrollHeight, clientHeight } = container;

      // 判断是否滚动到底部
      if (scrollTop + clientHeight >= scrollHeight - 10) {
        this.loadMore();
      }

      // 判断是否滚动到顶部
      if (scrollTop <= 0) {
        this.showRefreshHint = true;
        this.refreshData();
      } else {
        this.showRefreshHint = false;
      }

      // 保存当前滚动位置
      this.lastScrollTop = scrollTop;
    },
    loadMore() {
      if (this.loadingMore) return; // 防止重复加载
     // this.loadingMore = true;

      // 模拟异步加载
     // setTimeout(() => {
        this.visibleCount += 20; // 每次加载更多条目
        this.loadingMore = false;
      //}, 1000);
    },
    refreshData() {
      // 模拟刷新数据
     // setTimeout(() => {
        this.visibleCount = 20; // 重置可见条目数
        this.showRefreshHint = false; // 隐藏刷新提示
     // }, 1000);
    },
  },
};
</script>

<style>
.container {
  height: 100vh;
  overflow-y: auto;
  position: relative;
  background:#f3f2f2;
}
ul{
  padding:0;
}
.refresh-hint {
  text-align: center;
  padding: 10px;
  background-color: #f0f0f0;
  position: sticky;
  top: 0;
  z-index: 10;
}
.loading {
  text-align: center;
  padding: 10px;
  background-color: #f0f0f0;
}
.item {
  height: 60px;
  display: flex;
  align-items: center;
  padding: 0 10px;
  background:#fff;
}
.item +.item{
  margin-top:10px;
}
</style>

在线地址:

Vue SFC Playground

相关文章:

  • Learn:C++ Primer Plus Chapter13
  • ChainLit快速接入DeepSeek实现一个深度推理的网站应用图文教程-附完整代码
  • Swift 并发任务的协作式取消
  • Mysql 安装教程和Workbench的安装教程以及workbench的菜单栏汉化
  • Python 常用内建模块-itertools
  • HTML(超文本标记语言)
  • Python FastApi(2):基础使用
  • 【SpringBoot】MorningBox小程序的完整后端接口文档
  • 第3章 Internet主机与网络枚举(网络安全评估)
  • Python 爬取 1688 详情接口数据返回说明
  • Mysql架构理论部分
  • github代理 | 快速clone项目
  • 简单理解机器学习中top_k、top_p、temperature三个参数的作用
  • 前端开发:Vue以及Vue的路由
  • AsyncHttpClient使用说明书
  • Android Compose 切换按钮深度剖析:从源码到实践(六)
  • SpringBoot @Scheduled注解详解
  • SQL宏-代替UDF
  • JSONPath 的介绍
  • 搭建主从DNS、nfs、nginx
  • 复旦大学与上海杨浦共建市东医院
  • 广州一饮品店取名“警茶”?市监局:取名没问题,但图像会产生误解
  • 美国三大指数全线高开:纳指涨逾4%,大型科技股、中概股大涨
  • 韩国总统选战打响:7人角逐李在明领跑,执政党临阵换将陷入分裂
  • 上海能源科技发展有限公司原董事长李海瑜一审获刑13年
  • 2025年上海好护士揭晓,上海护士五年增近两成达12.31万人