本文将系统讲解如何在 Vue + Element UI 项目中监听
el-scrollbar滚动与鼠标滚轮事件。内容涵盖基础监听、滚动到底加载更多、全局滚轮监听与自定义滚动控制等实战技巧,适合前端开发者收藏备用。
一、前言
在使用 Element UI 构建页面时,<el-scrollbar> 是一个非常常见的滚动容器组件。
然而很多开发者在使用时会遇到以下问题:
-
想监听滚动条滚动事件,却发现没触发?
-
想判断滚动到底部以加载更多?
-
想捕获鼠标滚轮方向、速度或阻止默认滚动行为?
本文将通过详细的示例代码,带你全面掌握这类滚动事件的监听方式。
二、基础滚动事件监听
在 Element UI 中,<el-scrollbar> 提供了 @scroll 事件,我们可以直接通过它获取当前滚动距离。
<template>
<el-scrollbar
height="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-scrollbar
ref="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-scrollbar
ref="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 事件,可以让你的前端页面既优雅又智能。
推荐延伸阅读:
4768

被折叠的 条评论
为什么被折叠?



