Uniapp微信小程序中实现顶部导航下拉菜单效果

Gary Chen
Uniapp微信小程序中实现顶部导航下拉菜单效果

在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>

注意事项

  1. 自定义导航栏适配

    • 微信小程序需要使用 uni.getMenuButtonBoundingClientRect() 获取胶囊按钮位置信息
    • 需要正确处理状态栏高度和导航栏高度
  2. 动画效果优化

    • 可以添加过渡动画使下拉更平滑
    .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;
    }
    
  3. 多平台兼容

    • 使用条件编译处理不同平台的差异
    // #ifdef MP-WEIXIN
    // 微信小程序特有逻辑
    // #endif
    
  4. 性能考虑

    • 避免在菜单项过多时影响性能,可考虑虚拟列表
  5. 交互体验

    • 点击菜单外部区域应关闭下拉菜单
    • 可以添加点击反馈效果提升用户体验

这个实现方案模拟了腾讯元宝小程序的下拉菜单效果,你可以根据实际需求调整样式和交互细节。