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 | 获取 scrollTop 、scrollLeft |
滚动到底部加载 | 计算 scrollTop + clientHeight >= scrollHeight | 懒加载场景 |
监听鼠标滚轮 | addEventListener('wheel') | 捕获滚轮方向与力度 |
阻止默认滚动 | preventDefault() + { passive: false } | 自定义滚动行为 |
获取真实滚动容器 | this.$refs.scrollbar.wrap | el-scrollbar 的内部 DOM |
七、总结
掌握 el-scrollbar
的滚动与鼠标滚轮监听,是提升 Vue 界面交互体验的重要一环。
通过本文讲解的四种常用监听方法,你可以:
-
精确控制滚动加载;
-
捕获用户滚动行为;
-
实现流畅的自定义滚动或动画交互。
灵活运用 @scroll
与 wheel
事件,可以让你的前端页面既优雅又智能。
推荐延伸阅读:
-
Element UI 官方文档:el-scrollbar
-
MDN:WheelEvent