Nuxt3(Vue3)实现滚动隐藏顶部信息栏、导航栏固定效果
Nuxt3 滚动隐藏信息栏+固定导航栏实现方案
核心逻辑:在两个组件的共同父级(通常是layouts/default.vue默认布局文件)统一监听页面滚动事件,维护滚动状态,分别控制信息栏隐藏、导航栏固定,同时给内容区加对应偏移避免被固定导航遮挡。
- 页面滚动距离小于顶部信息栏高度时:保持原有静态布局,barinfo正常显示,navbar随文档流排列
- 页面滚动距离超过barinfo高度时:barinfo平滑向上收起隐藏,navbar切换为固定定位吸附在页面顶部
具体实现步骤
1. 编写父组件共享滚动逻辑
修改默认布局文件layouts/default.vue,统一处理滚动监听和状态分发:
<template> <div class="site-wrapper"> <Barinfo :is-scrolled="isScrolled" /> <Navbar :is-scrolled="isScrolled" /> <!-- 导航固定时给内容区加顶部偏移,避免内容被遮挡 --> <main class="site-content" :class="{ 'nav-fixed': isScrolled }"> <slot /> </main> </div> </template> <script setup> const isScrolled = ref(false) // 滚动触发阈值,和barinfo实际高度保持一致即可 const scrollThreshold = 40 const handleScroll = () => { const scrollTop = window.scrollY || document.documentElement.scrollTop isScrolled.value = scrollTop > scrollThreshold } onMounted(() => { // 绑定滚动监听时加passive参数,优化滚动性能 window.addEventListener('scroll', handleScroll, { passive: true }) }) onBeforeUnmount(() => { // 组件卸载时移除监听,避免内存泄漏 window.removeEventListener('scroll', handleScroll) }) </script> <style scoped> .site-content.nav-fixed { /* 数值和导航栏实际高度匹配,可根据渲染效果微调 */ padding-top: 70px; } </style>
2. 修改Barinfo信息栏组件
给组件加平滑隐藏的过渡样式:
<template> <div class="barinfo-container" :class="{ 'hidden': isScrolled }"> <div class="container h-25 navbar navbar-expand-lg bg-dark text-white d-flex justify-content-between"> <div class="infol"> Lundi - Vendredi, 7h30 à 19h / Samedi - J feriés, 8h à 12h</div> <div class="infor">Appelez nous sur 05 35 51 70 30</div> </div> </div> </template> <script setup> defineProps({ isScrolled: { type: Boolean, default: false } }) </script> <style scoped> .barinfo-container { overflow: hidden; height: 40px; /* 0.3秒平滑过渡,和导航栏动画时长保持一致 */ transition: all 0.3s ease; } .barinfo-container.hidden { height: 0; opacity: 0; } </style>
3. 修改Navbar导航栏组件
给导航栏加固定定位样式:
<template> <div class="navbar-wrapper" :class="{ 'navbar-fixed': isScrolled }"> <nav class="navbar navbar-expand-lg top-navbar bg-light w-100"> <div class="container"> <div class="col-5"> <a class="infol navbar-brand" href="/"> <img src="/assets/images/logo.png" height="50" /> </a> </div> <div class="col-7"> <ul class="nav navbar-nav justify-content-end"> <li class="nav-item"> <NuxtLink class="nav-link" to="/">ACCEUIL</NuxtLink> </li> <li class="nav-item"> <NuxtLink class="nav-link" to="/qui-sommes-nous">QUI SOMMES NOUS</NuxtLink> </li> <li class="nav-item"> <a class="nav-link" href="https://pubmed.ncbi.nlm.nih.gov/?term=biognach">PUBLICATIONS</a> </li> <li class="nav-item"> <NuxtLink class="nav-link" to="/analyses">ANALYSES</NuxtLink> </li> <li class="nav-item"> <NuxtLink class="nav-link" to="/contact">CONTACT</NuxtLink> </li> <li class="nav-item"> <NuxtLink class="nav-link" to="/rendez-vous"> <button type="button" class="btn btn-success">PRENDRE RENDEZ VOUS</button> </NuxtLink> </li> </ul> </div> </div> </nav> </div> </template> <script setup> defineProps({ isScrolled: { type: Boolean, default: false } }) </script> <style scoped> .navbar-wrapper { position: relative; z-index: 1030; transition: all 0.3s ease; } .navbar-wrapper.navbar-fixed { position: fixed; top: 0; left: 0; width: 100%; /* 可选:固定时加阴影提升层次感 */ box-shadow: 0 2px 8px rgba(0,0,0,0.1); } </style>
可选优化项
- 可以在Barinfo组件挂载后通过
ref获取实际渲染高度,动态替换父组件中固定的scrollThreshold值,适配不同屏幕下的高度变化 - 给滚动事件加节流处理,减少高频滚动时的状态更新次数,进一步提升性能
- 移动端适配时记得调整
.nav-fixed的padding-top数值,和移动端导航实际高度匹配
内容的提问来源于stack exchange,提问作者YaDev
相关产品推荐
相关产品推荐

