UniApp 实现顶部固定导航栏 Tab 及滚动变色效果
顶部导航栏是一个非常常见的组件,尤其是固定在顶部的 Tab 导航,既能方便用户快速切换内容,又能保持页面结构的清晰。本文将详细介绍如何在 UniApp + Vue3 + TypeScript 项目中实现一个固定在顶部、且能根据滚动状态改变样式的 Tab 导航栏。
效果展示
我们要实现的导航栏具有以下特点:
- 固定在页面顶部,不随滚动消失
- 滚动超过一定距离时,导航栏背景色发生变化(带动画过渡)
- 支持 Tab 切换,并高亮显示当前选中项
- 自适应不同设备的状态栏高度
实现思路
- 使用
sticky
定位实现导航栏固定顶部效果 - 通过
onPageScroll
监听页面滚动事件,判断滚动距离 - 根据滚动距离动态切换导航栏样式
- 利用 UniApp 提供的 API 获取系统状态栏高度,实现适配
- 实现 Tab 切换的交互逻辑
代码实现与解析
<template><view class="header-bar"><!-- Tab导航栏 --><view class="tab-navigation" :style="{ paddingTop: navHeight || '50px' }":class="{ scrolled: isScrolled }"><view class="tab-wrapper"><viewv-for="(tab, index) in tabs":key="index"class="tab-item":class="{ active: currentIndex === index }"@click="changeTab(index)">{{ tab }}</view></view></view></view>
</template>
关键解析:
:style="{ paddingTop: navHeight || '50px' }"
:动态设置导航栏顶部内边距,用于适配不同设备的状态栏高度:class="{ scrolled: isScrolled }"
:根据滚动状态动态添加scrolled
类,实现样式切换v-for="(tab, index) in tabs"
:循环渲染 Tab 选项:class="{ active: currentIndex === index }"
:根据当前选中的索引值,为 Tab 项添加激活样式@click="changeTab(index)"
:绑定 Tab 切换事件
脚本逻辑(Script)
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { onPageScroll } from '@dcloudio/uni-app'// 导航栏高度相关
const navHeight = ref('')
const isScrolled = ref(false) // 滚动状态标记// 获取状态栏高度并设置导航高度
const setNavHeight = () => {// 获取系统信息const systemInfo = uni.getSystemInfoSync()// 使用状态栏高度,确保内容不被状态栏遮挡navHeight.value = systemInfo.statusBarHeight + 'px'
}// 监听页面滚动
onPageScroll((e: { scrollTop: number }) => {console.log(e.scrollTop)// 当滚动距离大于等于50px时,切换导航栏样式isScrolled.value = e.scrollTop >= 50
})// Tab相关数据
const tabs = ['推荐', '黄金', '白银', 'K金', '铂金']
const currentIndex = ref(0)// 切换Tab
const changeTab = (index: number) => {currentIndex.value = index
}// 组件挂载时设置导航高度
onMounted(() => {setNavHeight()
})
</script>
关键解析:
状态栏高度适配:
setNavHeight
函数通过uni.getSystemInfoSync()
获取系统信息,特别是状态栏高度- 在组件挂载时调用
setNavHeight
,确保导航栏正确适配不同设备滚动监听与状态切换:
- 使用 UniApp 提供的
onPageScroll
钩子监听页面滚动事件- 当滚动距离
scrollTop
大于等于 50px 时,将isScrolled
设置为true
,触发样式变化Tab 切换逻辑:
- 定义
tabs
数组存储导航项文本currentIndex
记录当前选中的 Tab 索引changeTab
方法用于切换选中的 Tab
样式设计(Style)
<style scoped>
.header-bar {display: flex;flex-direction: column;padding: 10rpx 20rpx;position: relative;width: 100vw;box-sizing: border-box;height: 2000rpx; /* 仅为演示设置的高度 */background-color: #d86868;transition: background-color 0.3s ease; /* 添加过渡动画 */
}/* 滚动后的导航栏样式 */
.scrolled {background-color: orange;z-index: 1000;
}/* Tab导航样式 */
.tab-navigation {display: flex;justify-content: center;padding: 10px 0;margin-top: 10rpx;position: sticky; /* 关键:sticky定位实现固定顶部效果 */top: 0; /* 固定在顶部 */z-index: 1000; /* 确保在其他元素之上 */
}.tab-wrapper {display: flex;justify-content: center;width: auto;
}.tab-item {color: #ffffff;font-size: 16px;padding: 5px 1px;margin: 0 21px;cursor: pointer;white-space: nowrap; /* 防止文本换行 */
}/* 激活状态的Tab样式 */
.tab-item.active {border-bottom: 2px solid #ffffff;color: #ffffff;
}
</style>