Vue3 实现一个无缝滚动组件(支持鼠标手动滚动)
Vue3 实现一个无缝滚动组件(支持鼠标手动滚动)
前言
在日常开发中,经常遇到需要支持列表循环滚动展示,特别是在数据化大屏开发中,无缝滚动使用频率更为频繁,在jquery时代,我们常用的无缝滚动组件为liMarquee,在vue中已经有vue-seamless-scroll组件(通过Vue2实现,不支持鼠标手动滚动),但是在使用过程中,发现滚动后会存在点击事件失效的问题,并且产品提了个需求,需要支持鼠标手动滚动,也要支持自动滚动,于是痛定思痛,决定通过Vue3来实现该功能,该组件已经实现上传npm,可以直接安装使用,链接在文尾。
实现
html部分
首先写一个基础的list结构,通过插槽接收外部传入的list数据,因为需要实现无缝滚动,需要复制出同一份的Dom,在最外层监听鼠标hover和leave的状态,以实现鼠标hover暂停滚动,绑定鼠标滚动事件,在鼠标滚动时记住滚动的位置,在恢复自动滚动时能从当前滚动位置继续滚动。
<div class="custom-list" ref="scrollBody" @mouseenter="mouseenterFunc" @mouseleave="mouseleaveFunc"@mousewheel="mousewheelFunc"><div class="list-body" :class="{'list-body2': isHorizontal}" ref="listBody" :style="{ transform: getScrollDistance() }"><slot></slot></div><div class="list-body" :class="{'list-body2': isHorizontal}" ref="tBody" v-if="isCanScroll" :style="{ transform: getScrollDistance() }"><slot></slot></div>
</div>
实现逻辑
开始
通过父级传入的isHorizontal判断是横向滚动,还是垂直滚动
const start = () => {//判断是否可以滚动函数let isScrollFunc = (bodySize:number, listSize:number) => {if (bodySize > listSize) {scrollDistance.value = 0;isCanScroll.value = !1;}};isStop.value = !1;//判断是否可以滚动if (!isHorizontal.value) {isScrollFunc(bodyHeight.value, listHeight.value);} else {isScrollFunc(bodyWidth.value, listWidth.value);}if (isCanScroll.value) {run();}
}
开始滚动
计算目前滚动的距离,并判断需要滚动的方向,计算下一步滚动的距离。
const run = () => {//清空动画clearAnimation();animationFrame.value = window.requestAnimationFrame(() => {//滚动主逻辑函数let main = (listSize:number, bodySize:number) => {let tempScrollDistance = Math.abs(scrollDistance.value);if (scrollDistance.value < 0) {let cc = 2 * listSize - bodySize;if (tempScrollDistance > cc) {scrollDistance.value = -(listSize - bodySize);}} else {scrollDistance.value = -listSize;}};//根据滚动方向判断使用高度或宽度控制效果if (!isHorizontal.value) {main(listHeight.value, bodyHeight.value);} else {main(listWidth.value, bodyWidth.value);}//判断滚动值if (!isStop.value) {if (props.scrollDirection === "top" ||props.scrollDirection === "left") {scrollDistance.value -= props.steep;} else if (props.scrollDirection === "bottom" ||props.scrollDirection === "right") {scrollDistance.value += props.steep;}run();}});
}
获取滚动样式
通过translate实现列表平移,已实现平滑滚动。
const getScrollDistance = () => {let style;if (!isHorizontal.value) {style = "translate(0px, " + scrollDistance.value + "px)";} else {style = "translate(" + scrollDistance.value + "px,0px)";}return style;
}
const clearAnimation = () => {if (animationFrame.value) {cancelAnimationFrame(animationFrame.value);animationFrame.value = null;}
}
鼠标滚动
鼠标滚动时实时计算滚动的距离,可通过传入的鼠标滚动速率来计算每次滚动多少。
const mousewheelFunc = (e:any) => {if (!isCanScroll.value || !props.isRoller) {return false;}let dis = e.deltaY;if (dis > 0) {scrollDistance.value -= props.rollerScrollDistance;} else {scrollDistance.value += props.rollerScrollDistance;}run();
}
使用
该组件已上传npm仓库,欢迎satrt使用
npm install @fcli/vue-auto-scroll --save-dev 来安装在项目中使用
import VueAutoScroll from '@fcli/vue-auto-scroll';
const app=createApp(App)
app.use(VueAutoScroll);
使用示例:
<div class="content"><vue-auto-scroll :data="list" :steep="0.5" scrollDirection="top" :isRoller="true" :rollerScrollDistance="50"><div class="li" v-for="i in list" :key="i">{{ i }}</div></vue-auto-scroll>
</div>
| 属性 | 属性名称 | 类型 | 可选值 |
|---|---|---|---|
| steep | 滚动的速率 | number | 为正数即可 |
| scrollDirection | 滚动的方向 | string | top ,bottom,left,right |
| isRoller | 是否可以使用滚轮滚动 | boolean | true,false |
| rollerScrollDistance | 滚轮滚动的速率 | number | (isRoller 必须为 true)为正数即可 |
| data | 接收异步数据 | array | 同步任务可不传 |
注: 当scrollDirection 为top或bottom时,一定要为 vue-auto-scroll 组件设置高度。 当scrollDirection 为left或right时,一定要为 vue-auto-scroll 组件设置宽度。并为嵌入vue-auto-scroll中的标签设置样式为display:inline-block; 示例样式名为list-item可以更改为其他类名。当scrollDirection 为left或right时,是基于行内元素的“white-space: nowrap;” 来控制强制不换行的。有可能会影响其内部的文字排列。可以在list-item 层添加 white-space: normal; 来处理给问题。并为其添加固定宽度,以保证文字可以正常换行及插件的正确计算与显示。如果没有为其添加固定宽度,会造成插件获取父容器层的宽度值错误,导致显示混乱
git地址:https://gitee.com/fcli/vue-auto-scroll.git
相关文章:
Vue3 实现一个无缝滚动组件(支持鼠标手动滚动)
Vue3 实现一个无缝滚动组件(支持鼠标手动滚动) 前言 在日常开发中,经常遇到需要支持列表循环滚动展示,特别是在数据化大屏开发中,无缝滚动使用频率更为频繁,在jquery时代,我们常用的无缝滚动组…...
【IP数据报】IP地址和MAC地址的区别
1、用IP地址来标识Internet的主机 在每个IP数据报中,都会携带源IP地址和目标IP地址来标识该IP数据报的源和目的主机。IP数据报在传输过程中,每个中间节点(IP 网关)还需要为其选择从源主机到目的主机的合适的转发路径(即路由)。IP协议可以根据路由选择协…...
高并发笔记
如何设计一个高并发系统?:https://mp.weixin.qq.com/s/yFc-70DEhloWn0G3GDa6Yw 分布式 ID 服务实践:https://mp.weixin.qq.com/s/KAts9Zjj8JpEd0Q6pqLlgQ 一文聊透布隆过滤器:https://mp.weixin.qq.com/s/qJ2fDm1Z57bPSzOBrgiqfg …...
eNSP网络学习
一、eNSP 1.什么是eNSP eNSP(Enterprise Network Simulation Platform)是一款由华为提供的免费的、可扩展的、图形化操作的网络仿真工具平台,主要对企业网络路由器、交换机进行软件仿真,完美呈现真实设备实景,支持大型网络模拟,让…...
广州xx策划公司MongoDB恢复-2023.09.09
2023.09.08用户的MongoDB数据库被勒索病毒攻击,数据全部被清空。 提示: mongoDB的默认端口为27017,黑客通常通过全网段扫描27017是否开放判断是否是MongoDB服务器。一旦发现27017开放,黑客就会用空密码、弱密码尝试连接数据库。黑…...
golang --- module-aware 模式下 包引入
一、文件列表如下 其中helloWorld目录是main包(package)所在目录,即该目录下所有的goy源文件(不包含子目录)属于main包,hello.go是mian函数所在文件 二、module-aware 模式启用 开启mod模式 go env -w G…...
从原理到实践 | Pytorch tensor 张量花式操作
文章目录 1.张量形状与维度1.1标量(0维张量):1.2 向量(1维张量):1.3矩阵(2维张量):1.4高维张量: 2. 张量其他创建方式2.1 创建全零或全一张量:2.2…...
无涯教程-JavaScript - TRANSPOSE函数
描述 TRANSPOSE函数将单元格的垂直范围作为水平范围返回,反之亦然。必须将TRANSPOSE函数作为数组公式输入,该范围必须具有与行范围和列范围相同的行和列数。 您可以使用TRANSPOSE在工作表上移动数组或范围的垂直和水平方向。 语法 TRANSPOSE (array)键入函数后,按CTRL SHI…...
Webserver项目解析
一.webserver的组成部分 Buffer类 用于存储需要读写的数据 Channel类 存储文件描述符和相应的事件,当发生事件时,调用对应的回调函数 ChannelMap类 Channel数组,用于保存一系列的Channel Dispatcher 监听器,可以设置为epo…...
Spring Cloud 篇
1、什么是SpringCloud ? Spring Cloud 流应用程序启动器是基于 Spring Boot 的 Spring 集成应用程序,提供与外部系统的集成。Spring cloud Task,一个生命周期短暂的微服务框架,用于快速构建执行有限数据处理的应用程序。 2、什么…...
vim,emacs,verilog-mode这几个到底是啥关系?
vim:不多说了被各类coder誉为地表最强最好用的编辑器;gvim,gui vim的意思; emacs:也是一个编辑器,类似vscode; vim在使用的时候为了增强其功能,有好多好多插件,都是以.…...
解决npm run build 打包出现XXXX.js as it exceeds the max of 500KB.
问题描述: npm run build 时出现下面的问题: Note: The code generator has deoptimised the styling of D:\base\node_modules\_element-ui2.15.12element-ui\lib\element-ui.common.js as it exceeds the max of 500KB.在项目的根目录加粗样式下找到 …...
Java 抖音小程序SDK
抖音小程序SDK,抖音SDK 码云地址:dy-open-sdk: 字节跳动,抖音小程序sdk...
Vue.js的服务器端渲染(SSR):为什么和如何
🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…...
Gin 打包vue或react项目输出文件到程序二进制文件
Gin 打包vue或react项目输出文件到程序二进制文件 背景解决方案1. 示例目录结构2. 有如下问题要解决:3. 方案探索 效果 背景 前后端分离已成为行业主流,vue或react等项目生成的文件独立在一个单独目录,与后端项目无关。 实际部署中,通常前面套…...
深度解析shell脚本的命令的原理之pwd
pwd是Print Working Directory的缩写,是一个Unix和Linux shell命令,用于打印当前工作目录的绝对路径。以下是对这个命令的深度解析: 获取当前工作目录:pwd命令通过调用操作系统提供的getcwd(或相应的)系统调…...
Kafka3.0.0版本——消费者(分区的分配以及再平衡)
目录 一、分区的分配以及再平衡1.1、消费者分区及消费者组的概述1.2、如何确定哪个consumer来消费哪个partition的数据1.3、消费者分区分配策略 一、分区的分配以及再平衡 1.1、消费者分区及消费者组的概述 一个consumer group中有多个consumer组成,一个 topic有多…...
Kotlin文件遍历FileTreeWalk filter
Kotlin文件遍历FileTreeWalk filter import java.io.Filefun main(args: Array<String>) {val filePath "."val file File(filePath)val fileTree: FileTreeWalk file.walk()fileTree//.maxDepth(1) //遍历层级1,不检查子目录.filter {it.isFile…...
Activiti兼容达梦数据库
1. 自定义类继承SpringProcessEngineConfiguration类,重写initDatabaseType方法。 package com.ydtf.cbda.module.cbdacim.improcess.config;import org.activiti.engine.ActivitiException; import org.activiti.spring.SpringProcessEngineConfiguration; import…...
shell 流程控制
流程控制 if条件判断 可以使用if来实现多路跳转,条件通常使用test命令 #if语句的语法if condition1then command1elif condition2 then command2else commandNfi 如果then需要和if放在同一行的话,使用;分隔 fi用来结束if语句,相当于…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
