在Uniapp微信小程序中实现顶部导航下拉菜单效果(类似腾讯元宝)
要实现类似腾讯元宝小程序顶部导航的下拉箭头点击显示菜单效果,可以按照以下步骤实现:
方案实现
1. 页面结构
<template>
<view class="container">
<!-- 自定义导航栏 -->
<view class="custom-navbar" :style="{paddingTop: statusBarHeight + 'px'}">
<view class="navbar-left">
<!-- 返回按钮或其他左侧内容 -->
</view>
<view class="navbar-title" @click="toggleDropdown">
{{ currentTitle }}
<view class="arrow" :class="{ 'rotate': showDropdown }">▼</view>
</view>
<view class="navbar-right">
<!-- 右侧按钮或其他内容 -->
</view>
<!-- 下拉菜单 -->
<view class="dropdown-menu" v-if="showDropdown" :style="{top: navbarHeight + statusBarHeight + 'px'}">
<view class="menu-item"
v-for="(item, index) in menuList"
:key="index"
@click="selectMenu(item)">
{{ item.title }}
</view>
</view>
</view>
<!-- 遮罩层 -->
<view class="mask"
v-if="showDropdown"
@click="toggleDropdown"></view>
</view>
</template>
2. 样式部分
/* 自定义导航栏 */
.custom-navbar {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 44px; /* 微信小程序导航栏标准高度 */
display: flex;
align-items: center;
justify-content: space-between;
background-color: #ffffff;
z-index: 999;
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.1);
}
.navbar-title {
position: relative;
display: flex;
align-items: center;
font-size: 16px;
font-weight: bold;
padding: 0 10px;
}
.arrow {
margin-left: 5px;
font-size: 12px;
transition: transform 0.3s ease;
}
.arrow.rotate {
transform: rotate(180deg);
}
/* 下拉菜单 */
.dropdown-menu {
position: absolute;
left: 50%;
transform: translateX(-50%);
width: 120px;
background-color: #fff;
border-radius: 8px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
overflow: hidden;
z-index: 1000;
}
.menu-item {
padding: 12px 15px;
text-align: center;
font-size: 14px;
border-bottom: 1px solid #f5f5f5;
}
.menu-item:last-child {
border-bottom: none;
}
.menu-item:active {
background-color: #f5f5f5;
}
/* 遮罩层 */
.mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.3);
z-index: 998;
}
3. JavaScript 逻辑
<script>
export default {
data() {
return {
statusBarHeight: 0, // 状态栏高度
navbarHeight: 44, // 导航栏高度
showDropdown: false, // 是否显示下拉菜单
currentTitle: '首页', // 当前标题
menuList: [
{ title: '首页', value: 'home' },
{ title: '发现', value: 'discover' },
{ title: '我的', value: 'mine' }
]
}
},
onLoad() {
// 获取状态栏高度
const systemInfo = uni.getSystemInfoSync()
this.statusBarHeight = systemInfo.statusBarHeight || 0
// 如果是自定义导航栏,需要计算胶囊按钮位置
// #ifdef MP-WEIXIN
const menuButtonInfo = uni.getMenuButtonBoundingClientRect()
this.navbarHeight = menuButtonInfo.bottom + menuButtonInfo.top - this.statusBarHeight
// #endif
},
methods: {
// 切换下拉菜单显示状态
toggleDropdown() {
this.showDropdown = !this.showDropdown
},
// 选择菜单项
selectMenu(item) {
this.currentTitle = item.title
this.showDropdown = false
// 根据选择的值执行相应操作
switch(item.value) {
case 'home':
uni.switchTab({ url: '/pages/home/index' })
break
case 'discover':
uni.navigateTo({ url: '/pages/discover/index' })
break
case 'mine':
uni.switchTab({ url: '/pages/mine/index' })
break
}
}
}
}
</script>
注意事项
-
自定义导航栏适配:
- 微信小程序需要使用
uni.getMenuButtonBoundingClientRect()
获取胶囊按钮位置信息 - 需要正确处理状态栏高度和导航栏高度
- 微信小程序需要使用
-
动画效果优化:
- 可以添加过渡动画使下拉更平滑
.dropdown-menu { transition: all 0.3s ease; opacity: 0; transform: translateX(-50%) translateY(-10px); visibility: hidden; } .dropdown-menu.show { opacity: 1; transform: translateX(-50%) translateY(0); visibility: visible; }
-
多平台兼容:
- 使用条件编译处理不同平台的差异
// #ifdef MP-WEIXIN // 微信小程序特有逻辑 // #endif
-
性能考虑:
- 避免在菜单项过多时影响性能,可考虑虚拟列表
-
交互体验:
- 点击菜单外部区域应关闭下拉菜单
- 可以添加点击反馈效果提升用户体验
这个实现方案模拟了腾讯元宝小程序的下拉菜单效果,你可以根据实际需求调整样式和交互细节。