1. 为什么要自定义导航栏
微信小程序默认的导航栏样式固定,只能修改背景色和文字颜色,无法满足品牌定制、沉浸式体验等需求。通过自定义导航栏,开发者可以完全控制导航栏的外观和交互,实现更灵活的设计。
自定义导航栏的核心思路是:在页面配置中关闭默认导航栏,然后自己在页面顶部绘制一个导航栏区域,并通过状态栏高度和胶囊按钮位置来适配不同机型。
2. 基础配置:关闭默认导航栏
在页面的 JSON 配置文件中,将 navigationStyle 设置为 custom,即可关闭该页面的默认导航栏。
json
{
"navigationStyle": "custom"
}
如果希望全局生效,可以在 app.json 的 window 节点中配置:
json
{
"window": {
"navigationStyle": "custom"
}
}
需要注意的是,关闭默认导航栏后,页面内容会延伸到屏幕顶部,包括状态栏区域,因此需要自行处理状态栏的占位问题。
3. 获取状态栏高度和胶囊按钮位置
自定义导航栏时,需要知道两个关键数据:状态栏高度和胶囊按钮(右上角胶囊)的位置。这两个数据可以通过微信提供的 API 获取。
javascript
// 获取状态栏高度
const systemInfo = wx.getSystemInfoSync();
const statusBarHeight = systemInfo.statusBarHeight;
// 获取胶囊按钮位置
const menuButton = wx.getMenuButtonBoundingClientRect();
其中 statusBarHeight 是状态栏的高度,menuButton 对象包含胶囊按钮的 top、bottom、height 等信息。导航栏的总高度通常可以这样计算:
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 获取状态栏高度和胶囊按钮位置、将导航栏封装为可复用组件。掌握这些要点后,就可以根据业务需求灵活定制导航栏的样式和交互了。