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

Vue + Element UI 实现 el-scroll 滚动与鼠标滚轮监听全攻略

本文将系统讲解如何在 Vue + Element UI 项目中监听 el-scrollbar 滚动与鼠标滚轮事件。内容涵盖基础监听、滚动到底加载更多、全局滚轮监听与自定义滚动控制等实战技巧,适合前端开发者收藏备用。


一、前言

在使用 Element UI 构建页面时,<el-scrollbar> 是一个非常常见的滚动容器组件。
然而很多开发者在使用时会遇到以下问题:

  • 想监听滚动条滚动事件,却发现没触发?

  • 想判断滚动到底部以加载更多?

  • 想捕获鼠标滚轮方向、速度或阻止默认滚动行为?

本文将通过详细的示例代码,带你全面掌握这类滚动事件的监听方式。


二、基础滚动事件监听

在 Element UI 中,<el-scrollbar> 提供了 @scroll 事件,我们可以直接通过它获取当前滚动距离。

<template><el-scrollbarheight="300px"@scroll="handleScroll"><div v-for="i in 100" :key="i" style="padding: 8px;">内容 {{ i }}</div></el-scrollbar>
</template><script>
export default {methods: {handleScroll({ scrollTop, scrollLeft }) {console.log('当前滚动位置:', scrollTop, scrollLeft);}}
}
</script>

要点说明

  • 事件参数是一个对象,包含:

    {scrollTop: number,scrollLeft: number
    }
    
  • 可用于实现滚动吸顶、返回顶部按钮显示、滚动动画触发等场景。

  • 只有设置了固定高度(例如 "300px")的容器才会出现滚动条,否则不会触发滚动事件。


三、监听滚动到底部(加载更多)

懒加载或“无限滚动”是最常见的滚动监听场景。
实现思路是通过判断:

scrollTop + clientHeight >= scrollHeight

来确定滚动是否到底。

<template><el-scrollbarref="scrollbar"height="400px"@scroll="onScroll"><div v-for="item in list" :key="item" style="padding: 10px;">{{ item }}</div></el-scrollbar>
</template><script>
export default {data() {return {list: Array.from({ length: 30 }, (_, i) => i + 1),loading: false}},methods: {async onScroll({ scrollTop }) {const wrap = this.$refs.scrollbar.wrap; // 实际滚动容器const { scrollHeight, clientHeight } = wrap;// 判断是否触底if (!this.loading && scrollTop + clientHeight >= scrollHeight - 5) {this.loading = true;console.log('触底,加载更多...');await this.loadMore();this.loading = false;}},loadMore() {return new Promise(resolve => {setTimeout(() => {const len = this.list.length;this.list.push(...Array.from({ length: 10 }, (_, i) => len + i + 1));resolve();}, 1000);});}}
}
</script>

小贴士

  • this.$refs.scrollbar.wrap 是真正滚动的容器,不是最外层组件。

  • -5 是为了避免精度误差造成触底不触发。

  • 加入 loading 状态避免多次触发加载。


四、监听鼠标滚轮事件(wheel)

有时我们需要捕获 鼠标滚轮 的滚动方向或速度,而不是依赖滚动条本身。
此时可以通过 addEventListener('wheel') 来实现。

在 el-scrollbar 内部监听

<template><el-scrollbarref="scrollbar"height="300px"><div v-for="i in 100" :key="i" style="padding: 8px;">内容 {{ i }}</div></el-scrollbar>
</template><script>
export default {mounted() {const wrap = this.$refs.scrollbar.wrap;wrap.addEventListener('wheel', this.handleWheel, { passive: true });},beforeDestroy() {const wrap = this.$refs.scrollbar.wrap;wrap.removeEventListener('wheel', this.handleWheel);},methods: {handleWheel(event) {console.log('鼠标滚轮事件:',event.deltaY > 0 ? '向下滚动' : '向上滚动','滚动量:', event.deltaY);}}
}
</script>

✅ 在全局(window)监听

mounted() {window.addEventListener('wheel', this.handleGlobalWheel, { passive: true });
},
beforeDestroy() {window.removeEventListener('wheel', this.handleGlobalWheel);
},
methods: {handleGlobalWheel(e) {if (e.deltaY > 0) console.log('页面滚轮向下');else console.log('页面滚轮向上');}
}

常见属性说明

属性含义示例值
event.deltaY垂直滚轮值(下为正,上为负)120 / -120
event.deltaX水平滚轮值0 / ±120
event.ctrlKey是否按下 Ctrl(用于缩放)true / false
event.deltaMode滚动单位(像素 / 行 / 页)0:像素;1:行;2:页

五、阻止默认滚动,实现自定义控制

如果希望完全接管鼠标滚轮(例如分页滚动、动画控制等),
可以通过 preventDefault() 来禁用默认滚动行为。

mounted() {const wrap = this.$refs.scrollbar.wrap;wrap.addEventListener('wheel', this.customWheel, { passive: false });
},
methods: {customWheel(e) {e.preventDefault(); // 阻止默认滚动if (e.deltaY > 0) {this.nextPage();} else {this.prevPage();}}
}

注意:

  • 当使用 e.preventDefault() 时,必须设置 { passive: false }

  • 这种方式常用于“整页切换”效果或滚动驱动动画。


六、快速总结

目标实现方式说明
监听滚动位置@scroll获取 scrollTopscrollLeft
滚动到底部加载计算 scrollTop + clientHeight >= scrollHeight懒加载场景
监听鼠标滚轮addEventListener('wheel')捕获滚轮方向与力度
阻止默认滚动preventDefault() + { passive: false }自定义滚动行为
获取真实滚动容器this.$refs.scrollbar.wrapel-scrollbar 的内部 DOM

七、总结

掌握 el-scrollbar 的滚动与鼠标滚轮监听,是提升 Vue 界面交互体验的重要一环。
通过本文讲解的四种常用监听方法,你可以:

  • 精确控制滚动加载;

  • 捕获用户滚动行为;

  • 实现流畅的自定义滚动或动画交互。

灵活运用 @scrollwheel 事件,可以让你的前端页面既优雅又智能。


推荐延伸阅读:

  • Element UI 官方文档:el-scrollbar

  • MDN:WheelEvent

http://www.dtcms.com/a/494412.html

相关文章:

  • vue2版本的ruoyi-ui中使用vxe-table插件
  • 全国建设网站郑州seo优化公司
  • 用观察者模式通知UI刷新数据
  • 基于 AI 大模型的 UI 元素定位浏览器插件
  • Prism框架核心对象全解析
  • 阿里云服务器上部署Mosquitto
  • Android 设计模式实战手册(Kotlin 实战版)
  • Android thermal (5)_cooling device(下)
  • 活字格低代码平台实现移动端应用(安卓 /iOS)打包的技术方案与实践指南
  • SpringBoot电子商城系统
  • 解析 Qt Remote Objects:从框架原理到 Repcs 实践,以正点原子 RK3588 UI 系统为例
  • 【底层机制】【Android】Binder架构与原理
  • 揭阳市住房和城乡建设局网站网站类游戏网站开发
  • DeviceNet 转 MODBUS TCP罗克韦尔 ControlLogix PLC 与上位机在汽车零部件涂装生产线漆膜厚度精准控制的通讯配置案例
  • 【STM32项目开源】基于STM32的智能衣柜系统
  • python基于web的汽车班车车票管理系统/火车票预订系统/高铁预定系统 可在线选座
  • ssh终端管理多个k8s集群,快速切换配置
  • 景德镇建站公司全国建筑四库一平台
  • 奥运网站模板wordpress在 分栏
  • toLua[七] Examples 06_LuaCoroutine2分析
  • CAD如何生成等高线
  • Java并发工具类详解:Semaphore、CyclicBarrier与CountDownLatch
  • 御剑问情_附带自动假人版_大型3D仙侠类剧情闯关手游_Linux服务端_通用视频架设教程_GM授权网页后台_运营网页后台_安卓苹果IOS双端
  • 基于信息保留与细粒度特征聚合的无人机目标检测
  • AINode部署全指南:从独立部署到Kubernetes集群部署
  • PYcharm——获取天气
  • Kafka多网卡环境配置
  • TypeScript 与淘宝 API:构建类型安全的商品数据查询前端 / Node.js 服务
  • 网站备案名称要求郴州网站排名优化
  • 百度做一个网站多少钱sns营销