微信小程序自定義導航欄兼容適配所有機型

目前小程序已在前端占了一席之地,最近公司項目上用的就是小程序開發,由于功能及頁面不是很多,所以直接原生開發,畢竟坑可能會少點,在開發過程中,小程序自帶導航欄和客戶的設計稿導航欄排在一起,感覺很別扭,因此要求去掉微信的自帶導航欄,微信提供了這方面的api,接下來我們就實操。

微信小程序自定義導航欄兼容適配所有機型

這是小程序官方文檔截圖,可以看到導航欄樣式支持兩種,默認是帶導航欄,另外一種是自定義導航欄-custom,如果使用自定義導航欄,我們可以

全局配置

//app.json
"window": {
"navigationStyle": "custom"
}

單頁面配置

//page.json
{
"navigationStyle": "custom"
}

效果對比

微信小程序自定義導航欄兼容適配所有機型

能明顯的看出來,自定義導航欄頁面內容已經頂到屏幕頂端,除了膠囊按鈕,其他都是頁面可控區域。每個手機的屏幕都不一樣,各家系統的狀態欄高度也不一樣,因此,我們在開發頁面時要考慮屏幕的適配,有劉海的,要留出劉海的距離,沒有的,要把狀態欄高度留出來。

1.獲取導航欄高度及按鈕位置

微信提供了獲取導航欄高度的Api和膠囊按鈕位置的Api

// 系統信息
const systemInfo = wx.getSystemInfoSync();
// 膠囊按鈕位置信息
const menuButtonInfo = wx.getMenuButtonBoundingClientRect();

在控制台打印出這兩個Api返回結果

微信小程序自定義導航欄兼容適配所有機型

這裏面我們只說幾個我們接下來用到的參數。

statusBarHeight // 狀態欄高度
screenWidth // 膠囊的寬度

top // 膠囊到頂部距離
height // 膠囊的高度
right // 膠囊距離右邊的距離

通過這幾個參數,我們可以計算出狀態欄的高度,微信膠囊所占的高度(存在padding值,可以使元素和膠囊縱向居中)

首先在app.js中定義全局data-globalData

globalData: {
navBarHeight: 0, // 導航欄高度
menuBotton: 0, // 膠囊距底部間距(保持底部間距一致)
menuRight: 0, // 膠囊距右方間距(方保持左、右間距一致)
menuHeight: 0, // 膠囊高度(自定義內容可與膠囊高度保證一致)
},

新建個方法

setNavBarInfo() {
// 獲取系統信息
const systemInfo = wx.getSystemInfoSync();
// 膠囊按鈕位置信息
const menuButtonInfo = wx.getMenuButtonBoundingClientRect();
// 導航欄高度 = 狀態欄到膠囊的間距(膠囊距上距離-狀態欄高度) * 2 + 膠囊高度 + 狀態欄高度
this.globalData.navBarHeight = (menuButtonInfo.top - systemInfo.statusBarHeight) * 2 + menuButtonInfo.height + systemInfo.statusBarHeight;
this.globalData.menuBotton = menuButtonInfo.top - systemInfo.statusBarHeight;
this.globalData.menuRight = systemInfo.screenWidth - menuButtonInfo.right;
this.globalData.menuHeight = menuButtonInfo.right;
}

在onLaunch中調用,因爲我這個項目是所有的導航都不用微信自帶的,所以在app.js

中調用及設置data。

onLaunch() {
this.setNavBarInfo()
},

到這裏所需要用到的都已經存了起來,頁面用法也比較簡單,排除狀態欄的高度,設置導航欄的高度和膠囊高度保持,用flex布局。

2.頁面適配

首先page.js中定義變量

var app = getApp()
Page({
/**
* 頁面的初始數據
*/

data: {
navBarHeight: app.globalData.navBarHeight, //導航欄高度
menuBotton: app.globalData.menuBotton, //導航欄距離頂部距離
menuRight: app.globalData.menuRight, //導航欄距離右側距離
menuHeight: app.globalData.menuHeight, //導航欄高度
}
})

頁面使用

<view class="nav" style="height:{{navBarHeight}}px;">
<view class="nav-main">
<!-- 膠囊區域 -->
<view
class="capsule-box" style="style="height:{{menuHeight+menuBotton*2}}px; min-height:{{menuHeight}}px; line-height:{{menuHeight}}px; bottom:0px;padding:0 {{menuRight}}px;">

<!-- 導航內容區域 -->
<slot></slot>
</view>
</view>
</view>

wxss

/* 公共導航 */
.nav {
position: fixed;
top: 0;
left: 0;
box-sizing: border-box;
width: 100vw;
z-index: 1000;
}
.nav-main {
width: 100%;
height: 100%;
box-sizing: border-box;
position: relative;
}
.nav .capsule-box {
position: absolute;
box-sizing: border-box;
width: 100%;
display: flex;
align-items: center;
}

最終效果

微信小程序自定義導航欄兼容適配所有機型


此種適配方案適應所有手機,應該說是最優的選擇。