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

Vue:实现一个无线滚动列表的解决方案

在这里插入图片描述

文章目录

  • 前言
  • 一、解决方案
    • 1.方案1:
      • 实现思路
      • 完整实现代码
      • 代码解释
    • 方案2:方案1的进阶优化
      • 1.使用 CSS 动画实现平滑滚动
      • 2.添加动态数据更新功能
  • 总结


前言

vue 实现 move-box 区域 内容无限向上滚动 效果

<div class="warning-info"><div class="move-box" ref="moveBox"><div class="info-item" v-for="(item, index) in warningInfoList" :key="index"><div class="name">{{ item.name }}</div><div class="time">{{ item.time }}</div></div></div>
</div>

无线滚动(轮播)列表


一、解决方案

1.方案1:

要实现 move-box 区域内容无限向上滚动的效果,我们需要使用 Vue 的生命周期钩子和定时器来控制滚动位置。下面我将为你提供完整的实现方案。

实现思路

  1. 使用 CSS 设置 move-box 的固定高度和隐藏溢出内容
  2. 使用 Vue 的 ref 获取 move-box 元素
  3. 使用 setInterval 创建定时器,定期改变滚动位置
  4. 当滚动到底部时,重置滚动位置到顶部,形成无限滚动效果
  5. 在组件销毁时清除定时器,避免内存泄漏

完整实现代码

<template><div class="warning-info"><div class="move-box" ref="moveBox"><div class="info-item" v-for="(item, index) in warningInfoList" :key="index"><div class="name">{{ item.name }}</div><div class="time">{{ item.time }}</div></div></div></div>
</template><script>
export default {name: 'InfiniteScroll',data() {return {warningInfoList: [{ name: '设备1', time: '2023-05-20 10:30:45' },{ name: '设备2', time: '2023-05-20 10:31:22' },{ name: '设备3', time: '2023-05-20 10:32:15' },{ name: '设备4', time: '2023-05-20 10:33:08' },{ name: '设备5', time: '2023-05-20 10:34:30' },{ name: '设备6', time: '2023-05-20 10:35:12' },{ name: '设备7', time: '2023-05-20 10:36:45' },{ name: '设备8', time: '2023-05-20 10:37:22' }],scrollTimer: null,scrollSpeed: 50, // 滚动速度,数值越小滚动越快scrollDistance: 1, // 每次滚动的距离isPaused: false // 是否暂停滚动}},mounted() {this.startScroll();// 鼠标悬停时暂停滚动this.$refs.moveBox.addEventListener('mouseenter', this.pauseScroll);this.$refs.moveBox.addEventListener('mouseleave', this.resumeScroll);},beforeDestroy() {// 组件销毁前清除定时器和事件监听this.stopScroll();if (this.$refs.moveBox) {this.$refs.moveBox.removeEventListener('mouseenter', this.pauseScroll);this.$refs.moveBox.removeEventListener('mouseleave', this.resumeScroll);}},methods: {startScroll() {this.stopScroll(); // 确保没有多个定时器同时运行this.scrollTimer = setInterval(() => {if (!this.isPaused && this.$refs.moveBox) {const moveBox = this.$refs.moveBox;// 如果滚动到底部,重置到顶部if (moveBox.scrollTop >= moveBox.scrollHeight - moveBox.clientHeight) {moveBox.scrollTop = 0;} else {moveBox.scrollTop += this.scrollDistance;}}}, this.scrollSpeed);},stopScroll() {if (this.scrollTimer) {clearInterval(this.scrollTimer);this.scrollTimer = null;}},pauseScroll() {this.isPaused = true;},resumeScroll() {this.isPaused = false;}}
}
</script><style scoped>
.warning-info {width: 100%;height: 300px; /* 可以根据需要调整高度 */border: 1px solid #eee;border-radius: 4px;overflow: hidden;position: relative;
}.move-box {width: 100%;height: 100%;overflow-y: auto; /* 允许垂直滚动 */scrollbar-width: none; /* 隐藏滚动条 - Firefox */-ms-overflow-style: none; /* 隐藏滚动条 - IE/Edge */
}.move-box::-webkit-scrollbar {display: none; /* 隐藏滚动条 - Chrome/Safari/Opera */
}.info-item {padding: 10px 15px;border-bottom: 1px solid #f0f0f0;display: flex;justify-content: space-between;align-items: center;
}.info-item:last-child {border-bottom: none;
}.name {font-weight: bold;width: 30%;
}.time {color: #999;font-size: 0.9em;width: 30%;text-align: right;
}/* 可选:添加滚动动画效果 */
.move-box {scroll-behavior: smooth;
}
</style>

代码解释

数据结构:

warningInfoList:存储要显示的警告信息列表
scrollTimer:存储定时器的引用
scrollSpeed:控制滚动速度
scrollDistance:每次滚动的像素距离
isPaused:控制滚动是否暂停

生命周期钩子:

mounted:组件挂载后启动滚动,并添加鼠标悬停事件监听
beforeDestroy:组件销毁前清除定时器和事件监听,防止内存泄漏

方法:

startScroll:启动滚动定时器
stopScroll:停止滚动定时器
pauseScroll:暂停滚动
resumeScroll:恢复滚动

CSS 样式:

设置 .warning-info 和 .move-box 的尺寸和溢出处理
隐藏滚动条,使滚动效果更自然
设置 .info-item 的布局和样式

方案2:方案1的进阶优化

如果你想要更平滑的滚动效果或者更复杂的功能,可以考虑以下优化:

1.使用 CSS 动画实现平滑滚动

<template><div class="warning-info"><div class="move-box" ref="moveBox"><div class="content-wrapper" ref="contentWrapper"><div class="info-item" v-for="(item, index) in warningInfoList" :key="index"><div class="name">{{ item.name }}</div><div class="time">{{ item.time }}</div></div><!-- 复制一份内容以实现无缝滚动 --><div class="info-item" v-for="(item, index) in warningInfoList" :key="'copy-'+index"><div class="name">{{ item.name }}</div><div class="time">{{ item.time }}</div></div></div></div></div>
</template><script>
export default {name: 'SmoothInfiniteScroll',data() {return {warningInfoList: [// 数据同上],animationDuration: 20, // 动画持续时间(秒)isPaused: false}},mounted() {this.startAnimation();this.$refs.moveBox.addEventListener('mouseenter', this.pauseAnimation);this.$refs.moveBox.addEventListener('mouseleave', this.resumeAnimation);},beforeDestroy() {this.stopAnimation();if (this.$refs.moveBox) {this.$refs.moveBox.removeEventListener('mouseenter', this.pauseAnimation);this.$refs.moveBox.removeEventListener('mouseleave', this.resumeAnimation);}},methods: {startAnimation() {const contentWrapper = this.$refs.contentWrapper;if (contentWrapper) {// 计算内容高度的一半(因为我们复制了一份内容)const halfHeight = contentWrapper.scrollHeight / 2;// 设置动画contentWrapper.style.animation = `scroll ${this.animationDuration}s linear infinite`;// 定义CSS动画const style = document.createElement('style');style.innerHTML = `@keyframes scroll {0% { transform: translateY(0); }100% { transform: translateY(-${halfHeight}px); }}`;document.head.appendChild(style);}},stopAnimation() {const contentWrapper = this.$refs.contentWrapper;if (contentWrapper) {contentWrapper.style.animationPlayState = 'paused';}},pauseAnimation() {const contentWrapper = this.$refs.contentWrapper;if (contentWrapper) {contentWrapper.style.animationPlayState = 'paused';}},resumeAnimation() {const contentWrapper = this.$refs.contentWrapper;if (contentWrapper) {contentWrapper.style.animationPlayState = 'running';}}}
}
</script><style scoped>
.warning-info {width: 100%;height: 300px;border: 1px solid #eee;border-radius: 4px;overflow: hidden;position: relative;
}.move-box {width: 100%;height: 100%;overflow: hidden;
}.content-wrapper {width: 100%;
}.info-item {padding: 10px 15px;border-bottom: 1px solid #f0f0f0;display: flex;justify-content: space-between;align-items: center;
}.name, .time {/* 样式同上 */
}
</style>

2.添加动态数据更新功能

<template><div class="warning-info"><div class="move-box" ref="moveBox"><div class="info-item" v-for="(item, index) in displayList" :key="index"><div class="name">{{ item.name }}</div><div class="time">{{ item.time }}</div></div></div></div>
</template><script>
export default {name: 'DynamicInfiniteScroll',data() {return {warningInfoList: [// 初始数据],displayList: [], // 实际显示的列表scrollTimer: null,scrollSpeed: 50,scrollDistance: 1,isPaused: false,maxItems: 20 // 最大显示项目数}},created() {// 初始化显示列表this.updateDisplayList();// 模拟动态数据更新this.startDataUpdate();},mounted() {this.startScroll();this.$refs.moveBox.addEventListener('mouseenter', this.pauseScroll);this.$refs.moveBox.addEventListener('mouseleave', this.resumeScroll);},beforeDestroy() {this.stopScroll();this.stopDataUpdate();if (this.$refs.moveBox) {this.$refs.moveBox.removeEventListener('mouseenter', this.pauseScroll);this.$refs.moveBox.removeEventListener('mouseleave', this.resumeScroll);}},methods: {startScroll() {this.stopScroll();this.scrollTimer = setInterval(() => {if (!this.isPaused && this.$refs.moveBox) {const moveBox = this.$refs.moveBox;if (moveBox.scrollTop >= moveBox.scrollHeight - moveBox.clientHeight) {moveBox.scrollTop = 0;} else {moveBox.scrollTop += this.scrollDistance;}}}, this.scrollSpeed);},stopScroll() {if (this.scrollTimer) {clearInterval(this.scrollTimer);this.scrollTimer = null;}},pauseScroll() {this.isPaused = true;},resumeScroll() {this.isPaused = false;},startDataUpdate() {// 每30秒添加一条新数据this.dataUpdateTimer = setInterval(() => {const newIndex = this.warningInfoList.length + 1;const newItem = {name: `设备${newIndex}`,time: new Date().toLocaleString()};this.warningInfoList.push(newItem);this.updateDisplayList();}, 30000);},stopDataUpdate() {if (this.dataUpdateTimer) {clearInterval(this.dataUpdateTimer);this.dataUpdateTimer = null;}},updateDisplayList() {// 只保留最新的maxItems个项目if (this.warningInfoList.length > this.maxItems) {this.warningInfoList = this.warningInfoList.slice(-this.maxItems);}this.displayList = [...this.warningInfoList];}}
}
</script><style scoped>
/* 样式同上 */
</style>

总结

以上提供了三种实现无限向上滚动效果的方法:

  • 基础实现:使用定时器和 scrollTop 属性控制滚动,简单直接。
  • 平滑滚动:使用 CSS 动画实现更平滑的滚动效果,通过复制内容实现无缝滚动。
  • 动态数据:添加了动态更新数据的功能,适合实时数据展示场景。

根据你的具体需求,可以选择最适合的方案。基础实现适用于简单场景,平滑滚动提供更好的用户体验,而动态数据实现则适合需要实时更新数据的应用。

http://www.lryc.cn/news/619363.html

相关文章:

  • 【密码学实战】国密SM2算法介绍及加解密/签名代码实现示例
  • 2021 年全国硕士研究生招生考试真题笔记
  • 若依前后端分离版学习笔记(九)——登录和操作日志
  • Android中获取状态栏高度
  • 算法题打卡力扣第11题:盛最多水的容器(mid)
  • [AI React Web]`意图识别`引擎 | `上下文选择算法` | `url内容抓取` | 截图捕获
  • 【递归、搜索与回溯算法】穷举、暴搜、深搜、回溯、剪枝
  • BGE:智源研究院的通用嵌入模型家族——从文本到多模态的语义检索革命
  • 海洋通信系统技术文档(1)
  • 高可用实战之Nginx + Apache篇
  • QT常用类解析
  • ubuntu20.04下C++实现点云的多边形区域过滤(2种实现:1、pcl的CropHull滤波器;2、CUDA上实现射线法)
  • 在Ubuntu24.04中使用ssh连接本地git仓库到github远程仓库
  • C++QT HTTP与HTTPS的使用方式
  • 【网络安全测试】OWASP ZAP web安全测试工具使用指导及常用配置(有关必回)
  • Spring事务管理实战:从注解到进阶
  • Spring 源码学习(十)—— DispatcherServlet
  • 【一步AI】模型压缩:减小模型体积与计算量
  • YOLOv8 级联检测:在人脸 ROI 内检测眼镜(零改源码方案)
  • 第十六届蓝桥杯青少组C++省赛[2025.8.9]第二部分编程题(1 、庆典队列)
  • Excel怎么筛选重复项?【图文详解】查找/删除重复项?查找重复项公式?如何去重?
  • [QtADS]解析demo.pro
  • HarmonyOS NDK的JavaScript/TypeScript与C++交互机制
  • Electron自定义菜单栏及Mac最大化无效的问题解决
  • XML头部声明发送者信息的实现方法
  • C# 微软依赖注入 (Microsoft.Extensions.DependencyInjection) 详解
  • CV 医学影像分类、分割、目标检测,之【肝脏分割】项目拆解
  • windows常用的快捷命令
  • 机器学习实战·第三章 分类(2)
  • docker 容器内编译onnxruntime