VUE 弹框内容懒加载-真实项目

news2024/11/17 15:46:02

背景:VUE 页面,点击按钮,弹框,内容从接口获取,数据量比较大,鼠标滑到页面最底部,调取一次接口,分批加载;

demo:

<template>
  <div>
    <!-- 触发弹框的按钮 -->
    <el-button @click="dialogVisible = true">打开弹框</el-button>

    <!-- 数据加载中的提示 -->
    <el-loading v-if="loading" lock text="数据加载中,请稍候..."></el-loading>

    <!-- 弹框 -->
    <el-dialog
      :visible.sync="dialogVisible"
      title="大批量数据列表"
      @before-close="handleClose"
    >
      <div class="data-list" ref="dataList" @scroll="handleScroll">
        <!-- 使用 v-for 渲染数据列表 -->
        <div v-for="(item, index) in items" :key="index" class="data-item">
          {{ item }}
        </div>
      </div>

      <!-- 分页控件,点击加载更多 -->
      <el-button
        slot="footer"
        size="small"
        @click="loadMore"
        :disabled="loading"
        >加载更多</el-button
      >
    </el-dialog>
  </div>
</template>

<script>
export default {
  data() {
    return {
      dialogVisible: false, // 控制弹框显示
      loading: false, // 数据加载中
      items: [], // 数据列表
      currentPage: 1, // 当前页码
      pageSize: 200, // 每页数据量
      hasMore: true, // 是否还有更多数据
    };
  },
  methods: {
    // 加载更多数据
    loadMore() {
      console.log("调取loadMore方法");
      if (!this.hasMore) return;

      this.loading = true;
      this.currentPage++;

      // 模拟从接口获取数据
      this.fetchData(this.currentPage, this.pageSize)
        .then((data) => {
          this.items = this.items.concat(data);
          this.loading = false;

          // 判断是否还有更多数据
          if (data.length < this.pageSize) {
            this.hasMore = false;
          }
        })
        .catch((error) => {
          console.error("加载数据失败", error);
          this.loading = false;
        });
    },
    // 关闭弹框前的回调
    handleClose() {
      this.items = []; // 清空数据列表
      this.currentPage = 1;
      this.hasMore = true;
      this.loading = false; // 确保关闭弹框时停止加载
    },
    // 模拟获取数据的方法
    fetchData(page, pageSize) {
      return new Promise((resolve, reject) => {
        // 这里应该是调用你的 API 获取数据
        // 以下是一个模拟的数据响应示例
        const mockData = new Array(pageSize)
          .fill(null)
          .map((_, index) => `Item ${(page - 1) * pageSize + index + 1}`);
        setTimeout(() => {
          resolve(mockData);
        }, 1000);
      });
    },
    // 监听滚动事件,当滚动到底部时加载更多数据
    // handleScroll() {
    //   if (this.$refs.dataList && this.$refs.dataList.scroll) {
    //     const scrollContainer = this.$refs.dataList.scroll;
    //     if (
    //       scrollContainer.scrollTop + scrollContainer.clientHeight >=
    //       scrollContainer.scrollHeight - 10
    //     ) {
    //       this.loadMore();
    //     }
    //   }
    // },
    // 监听滚动事件,当滚动到底部时加载更多数据
    handleScroll(event) {
      // 获取滚动容器的引用
      const scrollContainer = event.target || this.$refs.dataList;

      // 确保 scrollContainer 是一个有效的 DOM 元素
      if (!scrollContainer) return;

      // 计算滚动位置
      const isAtBottom =
        scrollContainer.scrollTop + scrollContainer.clientHeight >=
        scrollContainer.scrollHeight - 10;

      // 只有在滚动到底部时才调用 loadMore 方法
      if (isAtBottom && this.hasMore) {
        console.log('zoujinqu')
        this.loadMore();
      }
    },
  },
  mounted() {
    // 监听滚动事件,当滚动到底部时加载更多数据
    // this.$refs.dataList.addEventListener('scroll', this.handleScroll);
    this.$nextTick(() => {
      if (this.$refs.dataList) {
        this.$refs.dataList.addEventListener("scroll", this.handleScroll);
      }
    });
  },
  beforeDestroy() {
    // 组件销毁前移除事件监听
    if (this.$refs.dataList) {
      this.$refs.dataList.removeEventListener("scroll", this.handleScroll);
    }
  },
};
</script>

<style scoped>
.data-list {
  max-height: 500px; /* 设置一个固定高度 */
  overflow-y: auto; /* 允许垂直滚动 */
}
.data-item {
  padding: 8px;
  border-bottom: 1px solid #eee;
}
</style>

真实项目:

弹框内容是分接口给的数据,分批次加载(其实跟分页是一回事),鼠标滑到最底部,调取一次接口,加载一次数据。

<template>
  <div>
    <div style="position: relative; transition: all ease 0.5s">
      <el-table :data="defectList" style="width: 100%">
        <el-table-column prop="logFileName" label="日志信息" :show-overflow-tooltip="true" width="140">
          <template slot-scope="scope">
            <span class="color-list cursor" @click="logInfo(scope.row.logFileId)">{{ scope.row.logFileName }}</span>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <el-dialog title="日志详情" :visible.sync="dialogVisible" width="800px" :before-close="closeDialog">
      <div class="data-list" ref="dataList" @scroll="handleScroll">
        <div>
          {{ logDataInfo }}
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script lang="ts">
import Vue from 'vue'
import { warn, downloadFetchFiles } from '@/utils/common'
import API from '@/api'
import { Base64 } from 'js-base64'

export default Vue.extend({
  components: {},
  props: {
    defectList: {
      type: Array,
      default: () => []
    },
    total: {
      type: Number,
      default: 0
    },
    onPageChange: {
      type: Function,
      default: () => {}
    }
  },
  data() {
    return {
      selectedRow: null,
      dialogVisible: false,
      logDataInfo: '',
      loading: false,
      hasMore: true,
      currentPage: 1, // 当前页数
      pageSize: 50000 // 每页数量,
    }
  },
  mounted() {
    this.$nextTick(() => {
      if (this.$refs.dataList) {
        this.$refs.dataList.addEventListener('scroll', this.handleScroll)
      }
    })
  },
  methods: {
    logInfo(id: string) {
      localStorage.setItem('IDD', id)
      this.dialogVisible = true
      this.loadMore()
    },
    // 加载数据
    async loadMore() {
      try {
        if (this.loading || !this.hasMore) return // 如果正在加载或没有更多数据了,则不再发送请求

        let id = localStorage.getItem('IDD')
        if(this.currentPage - 1 >= this.logTotal) {
          return false;
        }
        const response = await API.Defect.logDetailsData({
          page: this.currentPage,
          pageSize: this.pageSize,
          fileId: id
        })
        const data = Base64.decode(response.data.list)
        if (data) {
          this.logDataInfo = data
          this.currentPage++ // 当前页数加一
        } else {
          this.hasMore = false // 没有更多数据了
        }
      } catch (error) {
        warn(error, true)
      }
    },
    // 监听滚动事件,当滚动到底部时加载更多数据
    handleScroll(event: any) {
      // 获取滚动容器的引用
      const scrollContainer = event.target || this.$refs.dataList

      // 确保 scrollContainer 是一个有效的 DOM 元素
      if (!scrollContainer) return

      // 计算滚动位置
      const isAtBottom = scrollContainer.scrollTop + scrollContainer.clientHeight >= scrollContainer.scrollHeight - 10

      if (isAtBottom && this.hasMore) {
        console.log('zoujinqu')
        this.loadMore()
      }
    },
    closeDialog() {
      this.dialogVisible = false
      this.dataList = []
      this.loading = false
      this.hasMore = true
      this.currentPage = 1
    }
  },
  beforeDestroy() {
    // 组件销毁前移除事件监听
    if (this.$refs.dataList) {
      this.$refs.dataList.removeEventListener('scroll', this.handleScroll)
    }
  }
})
</script>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1614567.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

通用变频器ACS800-04M-0320-3可议价

商业别名&#xff1a;ACS800-04M-0320-3 产品编号&#xff1a;68279429 ABB 型号名称&#xff1a;ACS800-04M-0320-3 目录说明&#xff1a;ACS800-04M-0320-3&#xff1b; ACS800-04M-0320-3 Pcont.max:250kW, Icont.max:521A 原产地&#xff1a;芬兰 (FI) 海关税则号&#xf…

现代图形API综合比较:Vulkan | DirectX | Metal | WebGPU

Vulkan、DirectX、Metal 和 WebGPU 等低级图形 API 正在融合为类似于当前 GPU 构建方式的模型。 图形处理单元 (GPU) 是异步计算单元&#xff0c;可以处理大量数据&#xff0c;例如复杂的网格几何形状、图像纹理、输出帧缓冲区、变换矩阵或你想要计算的任何数据。 NSDT工具推荐…

springboot3 集成knife4j No endpoint GET /doc.html.

springboot3 集成knife4j 访问页面&#xff1a;http://127.0.0.1:8022/doc.html 提示&#xff1a; No endpoint GET /doc.html. 描述环境&#xff1a; java17 springboot3.2.0 knife4j的jar包 <dependency><groupId>com.github.xiaoymin</groupId><a…

vue实现周日历 日历按周切换 vue日程管理

实现的功能 1、点击今天&#xff1a;回到今日日期并选中今日日期&#xff0c;查当天数据 2、点击左箭头&#xff1a;切换上一周 3、点击右箭头&#xff1a;切换下一周 4、黄圆圈代表有日程提醒&#xff0c;点击选中&#xff0c;下方对应显示当前日程提醒的内容&#xff0c;没有…

打造稳定安全的亚马逊测评环境:关键步骤与要点一览

亚马逊测评环境的搭建是一项既复杂又需要深入细致考虑的工作&#xff0c;它涉及多方面的技术配置和资源准备。以下是一些关键步骤和要点&#xff0c;帮助您更高效地构建测评环境。 一、资源筹备 1. 养号系统&#xff1a;选择稳定、高效的养号系统&#xff0c;确保能够模拟真实…

上传文件到HDFS

1.创建文件夹 hdfs -dfs -mkdir -p /opt/mydoc 2.查看创建的文件夹 hdfs -dfs -ls /opt 注意改文件夹是创建在hdfs中的&#xff0c;不是本地&#xff0c;查看本地/opt&#xff0c;并没有该文件夹。 3.上传文件 hdfs dfs -put -f file:///usr/local/testspark.txt hdfs://m…

【JavaEE初阶系列】——网络原理之进一步了解应用层以及传输层的UDP协议

目录 &#x1f6a9;进一步讲应用层 &#x1f388;自定义应用层协议 &#x1f388;用什么格式组织 &#x1f469;&#x1f3fb;‍&#x1f4bb;xml(远古的数据组织格式) &#x1f469;&#x1f3fb;‍&#x1f4bb;json(当下最流行得一种数据组织格式) &#x1f469;&…

Docker(二)Docker+ server部署极简前端页面

本篇文章介绍如何使用 Dockerserver 将一个极简前端页面进行部署 1.本地运行一个简单的前端页面&#xff0c;再把它部署到服务器上 index.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name&quo…

算法思想总结:栈

一、栈的经典应用&#xff1a;波兰表达式与逆波兰表达式 我们平时看到的 12*&#xff08;3-4*5&#xff09;6/7 叫做中缀表达式&#xff0c;平时我们习惯用这个计算的原因是我们可以整体地去看到这个表达式并且清楚地知道各个运算符的优先级&#xff0c;但是计算机并不一定知道…

JavaScript之模块化规范详解

文章的更新路线&#xff1a;JavaScript基础知识-Vue2基础知识-Vue3基础知识-TypeScript基础知识-网络基础知识-浏览器基础知识-项目优化知识-项目实战经验-前端温习题&#xff08;HTML基础知识和CSS基础知识已经更新完毕&#xff09; 正文 CommonJS、UMD、CMD和ES6是不同的模块…

详解爬虫基本知识及入门案列(爬取豆瓣电影《热辣滚烫》的短评 详细讲解代码实现)

目录 前言什么是爬虫&#xff1f; 爬虫与反爬虫基础知识 一、网页基础知识 二、网络传输协议 HTTP&#xff08;HyperText Transfer Protocol&#xff09;和HTTPS&#xff08;HTTP Secure&#xff09;请求过程的原理&#xff1f; 三、Session和Cookies Session Cookies Session与…

核桃派全志H616实现VNC远程桌面教程

VNC远程桌面 核桃派预装了VNC服务器&#xff0c;VNC适应于局域网&#xff08;通常指同一个路由器网络下&#xff09;桌面登录。使用该服务前先确保核桃派已经通过以太网或无线WiFi连接到路由器。 使用核桃派桌面系统的时候由于要配置各类信息和联网&#xff0c;可以使用HDMI显…

【C语言】每日一题,快速提升(5)!

&#x1f525;博客主页&#x1f525;&#xff1a;【 坊钰_CSDN博客 】 欢迎各位点赞&#x1f44d;评论✍收藏⭐ 目录 1. strlen函数 2. strcpy函数 3. strcat函数 题目&#xff1a;模拟实现 strlen--strcpy--strcat--三个函数 1. strlen函数 字符串计算 #include <stdio.h…

硕士博士学位论文格式检查规范

包含标题、摘要、英文缩写、关键词、公式、表格、图片、参考文献&#xff0c;只能说太强了 学位论文检查三十六策点击蓝字 关注我们 写在前面 同学们撰写学位论文时&#xff0c;常常犯一些错误&#xff0c;既有格式错误&#xff0c;也有内容错误。本文列举36https://mp.weixin.…

【python】如何通过python来发送短信

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

SFP、SFP+、SFP28 与 QSFP28 收发器之间的差异:兼容性和性能

近年来&#xff0c;网络技术发展迅速&#xff0c;因此&#xff0c;计算专业人员面临着越来越令人困惑的术语和缩写词。 管理数据中心时必须了解的一个关键领域是收发器&#xff0c;特别是 SFP (1550nm/1310nm)、SFP (850nm) 和 QSFP28 (4x25G) 之间的差异。 这些型号在兼容性方…

【热门话题】常用经典目标检测算法概述

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 常用经典目标检测算法概述1. 滑动窗口与特征提取2. Region-based方法R-CNN系列M…

【日志】CSDN-AI助手升级日志

CSDN-AI助手升级日志 2023/04/05上线 支持点赞、收藏回访 关注回访&#xff08;对方至少有一条博客的记录&#xff09; 评论回访 私信检测到群发消息自动三连 OR 通过私信指令三连触发 bug优化 优化检测模式&#xff0c;防止出现多触发情况 为了防止操作额度不够&#xff0c…

Java面试八股之简述Servlet体系结构

简述Servlet体系结构 Servlet是Java Web开发中的核心组件&#xff0c;用于接收和响应HTTP请求&#xff0c;生成动态内容。它具有平台无关性、协议无关性和动态内容生成能力&#xff0c;遵循明确的生命周期。尽管现代Web开发中更多使用高级框架&#xff0c;但Servlet作为基础&a…

[笔试训练](二)

004 牛牛的快递_牛客题霸_牛客网 (nowcoder.com) 题目&#xff1a; 题解&#xff1a; 使用向上取整函数ceil()&#xff0c;&#xff08;记得添加头文件#include<cmath>&#xff09; #include <iostream> #include <cmath> using namespace std;int main(…