小程序自定义导航栏怎么写:从配置到实战

1. 为什么要自定义导航栏

微信小程序默认的导航栏样式固定,只能修改背景色和文字颜色,无法满足品牌定制、沉浸式体验等需求。通过自定义导航栏,开发者可以完全控制导航栏的外观和交互,实现更灵活的设计。

自定义导航栏的核心思路是:在页面配置中关闭默认导航栏,然后自己在页面顶部绘制一个导航栏区域,并通过状态栏高度和胶囊按钮位置来适配不同机型。

2. 基础配置:关闭默认导航栏

在页面的 JSON 配置文件中,将 navigationStyle 设置为 custom,即可关闭该页面的默认导航栏。

json 复制代码
{
  "navigationStyle": "custom"
}

如果希望全局生效,可以在 app.jsonwindow 节点中配置:

json 复制代码
{
  "window": {
    "navigationStyle": "custom"
  }
}

需要注意的是,关闭默认导航栏后,页面内容会延伸到屏幕顶部,包括状态栏区域,因此需要自行处理状态栏的占位问题。

3. 获取状态栏高度和胶囊按钮位置

自定义导航栏时,需要知道两个关键数据:状态栏高度和胶囊按钮(右上角胶囊)的位置。这两个数据可以通过微信提供的 API 获取。

javascript 复制代码
// 获取状态栏高度
const systemInfo = wx.getSystemInfoSync();
const statusBarHeight = systemInfo.statusBarHeight;

// 获取胶囊按钮位置
const menuButton = wx.getMenuButtonBoundingClientRect();

其中 statusBarHeight 是状态栏的高度,menuButton 对象包含胶囊按钮的 topbottomheight 等信息。导航栏的总高度通常可以这样计算:

javascript 复制代码
// 导航栏高度 = 胶囊按钮顶部到屏幕顶部的距离 + 胶囊按钮高度 + 胶囊按钮底部到导航栏底部的距离
const navBarHeight = (menuButton.top - statusBarHeight) * 2 + menuButton.height;

4. 编写自定义导航栏组件

推荐将自定义导航栏封装为组件,方便在多个页面复用。下面是一个完整的自定义导航栏组件示例。

首先是组件的 WXML 结构:

xml 复制代码
<view class="nav-bar" style="padding-top: {{statusBarHeight}}px;">
  <view class="nav-bar__content" style="height: {{navBarHeight}}px;">
    <view class="nav-bar__left" bindtap="handleBack">
      <text class="nav-bar__back" wx:if="{{showBack}}">‹</text>
    </view>
    <view class="nav-bar__title">{{title}}</view>
    <view class="nav-bar__right">
      <slot name="right"></slot>
    </view>
  </view>
</view>

然后是组件的 JS 逻辑:

javascript 复制代码
Component({
  properties: {
    title: {
      type: String,
      value: ''
    },
    showBack: {
      type: Boolean,
      value: true
    }
  },

  data: {
    statusBarHeight: 20,
    navBarHeight: 44
  },

  lifetimes: {
    attached() {
      const systemInfo = wx.getSystemInfoSync();
      const menuButton = wx.getMenuButtonBoundingClientRect();
      const statusBarHeight = systemInfo.statusBarHeight;
      const navBarHeight = (menuButton.top - statusBarHeight) * 2 + menuButton.height;

      this.setData({
        statusBarHeight,
        navBarHeight
      });
    }
  },

  methods: {
    handleBack() {
      const pages = getCurrentPages();
      if (pages.length > 1) {
        wx.navigateBack();
      } else {
        wx.switchTab({
          url: '/pages/index/index'
        });
      }
    }
  }
});

最后是组件的 WXSS 样式:

css 复制代码
.nav-bar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 999;
  background-color: #ffffff;
}

.nav-bar__content {
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

.nav-bar__left {
  position: absolute;
  left: 16rpx;
  height: 100%;
  display: flex;
  align-items: center;
  padding: 0 16rpx;
}

.nav-bar__back {
  font-size: 40rpx;
  color: #333333;
}

.nav-bar__title {
  font-size: 32rpx;
  font-weight: 500;
  color: #333333;
  max-width: 60%;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.nav-bar__right {
  position: absolute;
  right: 16rpx;
  height: 100%;
  display: flex;
  align-items: center;
}

5. 在页面中使用自定义导航栏

在页面的 JSON 文件中注册组件,并在 WXML 中使用:

json 复制代码
{
  "navigationStyle": "custom",
  "usingComponents": {
    "nav-bar": "/components/nav-bar/nav-bar"
  }
}
xml 复制代码
<nav-bar title="首页" show-back="{{false}}"></nav-bar>
<view class="page-content">
  <!-- 页面主体内容 -->
</view>

由于导航栏是固定定位,页面主体内容需要预留顶部空间,避免被导航栏遮挡:

css 复制代码
.page-content {
  padding-top: 88rpx; /* 根据实际导航栏高度调整 */
}

6. 常见问题与注意事项

  • 机型适配:不同机型的状态栏高度和胶囊按钮位置不同,务必通过 API 动态获取,不要写死数值。
  • 页面滚动 :导航栏使用 position: fixed 固定定位时,滚动页面时导航栏会保持在顶部,这是常见做法。
  • 返回逻辑:自定义导航栏后,默认的返回按钮消失,需要自行实现返回逻辑,并考虑页面栈深度。
  • 胶囊按钮遮挡:右侧自定义内容要避免与胶囊按钮重叠,建议预留足够的右侧空间。
  • 导航栏渐变:如果需要滚动渐变效果,可以监听页面滚动事件,动态修改导航栏的背景色和透明度。

7. 总结

自定义导航栏的关键在于三点:通过 navigationStyle: custom 关闭默认导航栏、通过 API 获取状态栏高度和胶囊按钮位置、将导航栏封装为可复用组件。掌握这些要点后,就可以根据业务需求灵活定制导航栏的样式和交互了。

相关推荐
liyinchi19882 小时前
微信小程序支付遇到“由于小程序违规,支付功能暂时无法使用” 解决办法
java·微信小程序·go
silianpan3 小时前
Office 文档预览 UTS 插件
android·微信小程序·harmonyos
微笑的曙光3 小时前
第三期 · 账号体系与双 Token 鉴权:让用户「无感登录,有感安全」
微信小程序
耀耀切克闹灬20 小时前
Skyline 渲染问题记录以及总结
微信小程序
小程序开发X1 天前
2026 深圳 APP 开发甄选:技术架构搭建、全流程落地、综合选型解读
微信小程序·小程序·app开发
EatFan1 天前
一个二维码背后的系统设计:批次生成、绑定、扫码与数据统计怎么做?
java·后端·微信小程序·二维码·qrcode
微笑的曙光2 天前
第一期 · 本地优先 MVP:不写一个后端,如何做出完整体验
微信小程序
EatFan2 天前
Java接入微信支付保姆式教程(三):SpringBoot 接入微信支付并完成统一下单
微信小程序·微信支付·springboot
QQ_21696290962 天前
基于SpringBoot+Vue的小生活平台的设计与实现
java·数据库·vue.js·spring boot·spring·微信小程序·生活