vue中实现带节流的滚动位置百分比监听,核心是监听window.scroll事件→实时计算0%~100%滚动进度→用节流控制触发频率以避免高频更新影响性能;需注意兼容性、初始值、移动端适配及精度处理。

Vue 中实现带节流的滚动位置百分比监听,核心是:监听 window.scroll 事件 → 实时计算滚动进度(0%~100%)→ 用节流控制触发频率,避免高频更新影响性能。
一、为什么需要节流
滚动事件每秒可能触发数十次,若每次都计算并响应百分比,容易造成:
- 不必要的响应式更新(尤其是 computed 或 watch 触发渲染)
- 频繁调用 DOM 查询(如
document.documentElement.scrollHeight) - 在低端设备或长列表页中出现卡顿
节流(throttle)确保单位时间内最多执行一次,兼顾实时性与性能。
二、Vue3 组合式 API 封装(推荐)
封装为可复用的 useScrollPercent hook,返回当前滚动百分比(0~100 的 number):
import { ref, onMounted, onUnmounted } from 'vue'
import { throttle } from 'lodash' // 或用轻量版 throttle 函数
<p>export default function useScrollPercent(delay = 100) {
const scrollPercent = ref(0)</p><p>const updatePercent = () => {
const { scrollTop, scrollHeight, clientHeight } = document.documentElement
const maxScroll = scrollHeight - clientHeight
if (maxScroll 100))
scrollPercent.value = Math.round(percent 100) / 100 // 保留两位小数
}</p><p>const throttledUpdate = throttle(updatePercent, delay)</p><p>onMounted(() => {
window.addEventListener('scroll', throttledUpdate)
})</p><p>onUnmounted(() => {
window.removeEventListener('scroll', throttledUpdate)
})</p><p>return { scrollPercent }
}</p>
使用方式:
import useScrollPercent from '@/hooks/useScrollPercent'
<p>const { scrollPercent } = useScrollPercent(160) // 每 160ms 最多更新一次</p><p>// 在模板中直接用:{{ scrollPercent }}%
// 或 watch:watch(scrollPercent, (val) => console.log(<code>${val}%</code>))</p>
三、不依赖第三方库的手写节流函数
如果不想引入 lodash,可用以下轻量实现(适用于多数场景):
function throttle(fn, delay) {
let lastTime = 0
return function (...args) {
const now = Date.now()
if (now - lastTime >= delay) {
fn(...args)
lastTime = now
}
}
}
替换 hook 中的 throttle(updatePercent, delay) 即可,零依赖、体积小、语义清晰。
四、注意事项与边界处理
实际应用中需注意几个关键细节:
-
兼容性:优先用
document.documentElement,fallback 到document.body(尤其在某些 iOS WebView 中) -
初始值:页面加载时可能已滚动(如刷新后恢复位置),建议在
onMounted后立即调用一次updatePercent() -
移动端适配:iOS Safari 中
body.scrollTop常为 0,必须用document.documentElement;部分安卓 WebView 需加overflow: hidden修复 -
精度取舍:
Math.round(x * 100) / 100比直接toFixed(2)更安全(避免字符串转换和潜在精度问题)
不复杂但容易忽略。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











