Vue3实现滚动隐藏导航栏问题求助(Script Setup语法)
问题解决与代码优化
核心问题分析
- previousScrollTop未持久化:每次调用
manageNavBarAnimations时,你都把当前scrollTop直接赋值给previousScrollTop,导致两者永远相等,根本无法判断滚动方向。 - 滚动事件绑定错误:你把
@scroll绑定在header元素上,但header是fixed定位,本身不会产生滚动行为,应该监听window的滚动事件。
修复后的完整代码
<template> <header :class="{ 'header-hidden': isHeaderHidden }"> <main-nav-organism></main-nav-organism> </header> </template> <script setup> import { ref, onMounted, onUnmounted } from 'vue' // 响应式变量控制导航栏显示状态 const isHeaderHidden = ref(false) // 持久化保存上一次滚动位置 let previousScrollTop = 0 const manageNavBarAnimations = () => { // 兼容不同浏览器的滚动距离获取 const scrollTop = document.documentElement.scrollTop || document.body.scrollTop // 判断滚动方向并更新状态 if (scrollTop > previousScrollTop && scrollTop > 80) { // 向下滚动且超过导航栏高度时隐藏 isHeaderHidden.value = true } else if (scrollTop < previousScrollTop) { // 向上滚动时显示 isHeaderHidden.value = false } // 更新上一次滚动位置 previousScrollTop = scrollTop } // 组件挂载时绑定滚动事件 onMounted(() => { window.addEventListener('scroll', manageNavBarAnimations) }) // 组件卸载时解绑事件,避免内存泄漏 onUnmounted(() => { window.removeEventListener('scroll', manageNavBarAnimations) }) </script> <style scoped> header { @apply fixed right-0 left-0 z-50 bg-slate-900 transition-all duration-300; top: 0; } .header-hidden { top: -80px; } </style>
优化说明
- 用响应式状态替代直接操作DOM:通过
isHeaderHidden控制class切换,更符合Vue的响应式设计思想,避免直接修改元素style。 - 添加节流优化(可选):滚动事件触发频率极高,可引入节流函数减少性能消耗,比如使用
lodash.throttle:import throttle from 'lodash.throttle' const throttledAnimation = throttle(manageNavBarAnimations, 100) onMounted(() => { window.addEventListener('scroll', throttledAnimation) }) onUnmounted(() => { window.removeEventListener('scroll', throttledAnimation) }) - 滚动阈值判断:只有当滚动距离超过导航栏高度(80px)时才触发隐藏逻辑,避免小幅度滚动误操作。
- 事件解绑处理:组件卸载时移除滚动事件监听,防止内存泄漏。
内容的提问来源于stack exchange,提问作者g4rf4z
相关产品推荐
相关产品推荐

