Vue3 实现页面上下滑动方案
在 Vue3 项目中,有时页面内容超高,导致鼠标滚轮或触控板无法触发滚动,这通常是因为未正确开启滚动容器或未绑定滚动事件。我们可以从以下几方面入手解决:
1️⃣ 使用滚动容器 + @scroll
最常见的方法是为内容外围元素(如 .scroll-container
)设置固定高度与 overflow-y: auto
,并监听其 scroll
事件:
<template>
<div class="scroll-container" @scroll="handleScroll" ref="scrollEl">
<!-- 内容区域 -->
<p v-for="i in 100" :key="i">第 {{ i }} 行内容</p>
</div>
</template>
<script setup>
import { ref } from 'vue';
const scrollEl = ref(null);
const scrollTop = ref(0);
function handleScroll(e) {
scrollTop.value = e.target.scrollTop;
}
</script>
<style>
.scroll-container {
height: 600px;
overflow-y: auto;
border: 1px solid #ccc;
}
</style>
这样不仅可以上下滑动,还能实时获取滚动位置信息 ([cnblogs.com][1])。
2️⃣ 使用 DOM 原生事件监听
若需要更灵活地控制或监听全局滚动,可以在 onMounted
中用 addEventListener
手动绑定:
import { ref, onMounted, onBeforeUnmount } from 'vue';
const scrollTop = ref(0);
function onScroll(e) {
const target = e.target === window ? document.documentElement : e.target;
scrollTop.value = target.scrollTop;
}
onMounted(() => {
window.addEventListener('scroll', onScroll, { passive: true });
});
onBeforeUnmount(() => {
window.removeEventListener('scroll', onScroll);
});
适合整个页面滚动监听,但请注意 防内存泄漏 。
3️⃣ 应用防抖/节流优化性能
滚动回调触发频繁,会导致性能问题。建议结合 lodash.debounce
或自定义节流机制:
import { debounce } from 'lodash-es';
const onScrollDebounced = debounce(onScroll, 100);
window.addEventListener('scroll', onScrollDebounced);
或使用 Vue Use 中的 useScroll
Hooks,一并自动处理性能优化 。
4️⃣ 实现「滚动到底部」监听
当需要触底加载更多内容时,可以通过如下逻辑判断:
function handleScroll(e) {
const el = e.target;
if (el.scrollTop + el.clientHeight >= el.scrollHeight - 5) {
// 已接近底部
loadMore();
}
}
这一思路被广泛用于「无限滚动」「触底刷新」场景 ([juejin.cn][2])。
5️⃣ 无缝滚动组件库支持
如果你需要不断自动滚动页面内容(如公告、数据流水等),推荐引入第三方组件库,如 vue3-seamless-scroll
:
npm install vue3-seamless-scroll
并在组件中这样使用:
<template>
<Vue3SeamlessScroll :list="items" :direction="'up'" :step="0.5" hover />
</template>
<script setup>
import { ref } from 'vue';
import { Vue3SeamlessScroll } from 'vue3-seamless-scroll';
const items = ref([/* 大量滚动内容数组 */]);
</script>
支持自动、无限滚动,效果流畅 ([juejin.cn][3])。
✅ 小结对照表
方案 | 触发方式 | 用途 | 性能建议 |
---|---|---|---|
@scroll + 容器 | 容器滚动 | 常规上下滑动 | 可 debouce |
window.addEventListener('scroll') | 页面滚动 | 全局滚动监听 | 移除时显式解绑 |
useScroll (VueUse) | 任意元素 | 滚动状态监测 | 内建性能优化 |
判断触底 | 滚动回调中判断 | 无线加载、分页 | scrollHeight 精度要加 buffer |
vue3-seamless-scroll | CSS/JS 自动滚动 | 内容轮播、公告滚动 | 无滚条体验,样式可自定义 |
💡 实用贴士
- 防抖/节流:滚动频繁触发建议引入机制;
- 解绑监听:避免内存泄漏;
- 容器样式:如果是内部滚动,需设置
overflow-y: auto
和固定高度; - 触底判断留白:根据业务需求设定合适 buffer (
>= scrollHeight - N
); - 使用组件库:有「自动无缝滚动」需求时,选用成熟组件可省力。
✅ 总结
在 Vue3 中,实现正常的上下滑动其实并不复杂,关键在于:
- 是否设置了滚动容器(overflow+y + 固定高度);
- 是否正确监听了滚动事件;
- 是否兼顾性能优化;
- 是否有分页或自动滚动的额外需求。