微信のナビゲーションバーは、JSON設定によりカスタマイズできますが、プロジェクトの要件によっては独自のナビゲーションバーが必要になる場合があります。以下のようなデザインの場合を想定します。
以下の手順に従って実装を行います。
実装手順:
1. app.json の "navigationStyle" を "custom" に変更
この設定を行うことで、ナビゲーションバーは右上の胶囊ボタンのみが残ります。
2. 各種値の計算
端末ごとにナビゲーションバーの高さが異なるため、複数の端末に対応するために以下の3つの値を計算する必要があります:
- ナビゲーションバー全体の高さ
- 胶囊ボタンから上部までの距離
- 胶囊ボタンから右端までの距離
微信では wx.getMenuButtonBoundingClientRect() で胶囊ボタンの情報を取得し、wx.getSystemInfo() で端末情報を取得できます。
これらの情報をもとに以下の式で計算します:
- ナビゲーションバーの高さ = statusBarHeight + height + (top - statusBarHeight) * 2
- 胶囊ボタンから上部までの距離 = top
- 胶囊ボタンから右端までの距離 = windowWidth - right
上記の式における2倍の係数は、表示領域の調整のためです。
App.js のコード例は以下の通りです:
App({
globalData: {},
onLaunch: function () {
let menuButtonObject = wx.getMenuButtonBoundingClientRect();
wx.getSystemInfo({
success: res => {
let statusBarHeight = res.statusBarHeight,
navTop = menuButtonObject.top,
navHeight = statusBarHeight + menuButtonObject.height + (menuButtonObject.top - statusBarHeight) * 2;
this.globalData.navHeight = navHeight;
this.globalData.navTop = navTop;
this.globalData.windowHeight = res.windowHeight;
},
fail(err) {
console.log(err);
}
})
}
})
3. 共通コンポーネントとしてナビゲーションバーを作成
コンポーネント名は「navbar」とします。
index.wxml:
<view class="navbar custom-class" style='height:{{navHeight}}px;background-color:{{bgColor}}'>
<view wx:if="{{showNav}}" class="navbar-action-wrap navbar-action-group row item-center" style='top:{{navTop}}px;background-color:rgba(255,255,255,.6)'>
<ss-icon name="back" color="{{iconColor}}" size="15px" block="{{true}}" class="navbar-action_item" bind:click="_navBack"></ss-icon>
<ss-icon name="index" color="{{iconColor}}" size="15px" block="{{true}}" class="navbar-action_item last" bind:click="_toIndex"></ss-icon>
</view>
<view class='navbar-title' style='top:{{navTop}}px'>
{{pageName}}
</view>
</view>
index.js:
// components/navbar/index.js
const App = getApp();
Component({
options: {
addGlobalClass: true,
},
properties: {
pageName: String,
showNav: {
type: Boolean,
value: true
},
showHome: {
type: Boolean,
value: true
}
},
data: {},
lifetimes: {
attached: function () {
this.setData({
navH: App.globalData.navHeight
})
}
},
methods: {
navBack: function () {
wx.navigateBack({
delta: 1
})
},
toIndex: function () {
wx.navigateTo({
url: '/pages/admin/home/index/index'
})
},
}
})
index.wxss:
/* components/navbar/index.wxss */
.navbar {
width: 100%;
overflow: hidden;
position: relative;
top: 0;
left: 0;
z-index: 10;
flex-shrink: 0;
}
.navbar-title {
width: 100%;
box-sizing: border-box;
padding-left: 115px;
padding-right: 115px;
height: 32px;
line-height: 32px;
text-align: center;
position: absolute;
left: 0;
z-index: 10;
color: #333;
font-size: 16px;
font-weight: bold;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.navbar-action-wrap {
display: -webkit-flex;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
-webkit-align-items: center;
align-items: center;
position: absolute;
left: 10px;
z-index: 11;
line-height: 1;
padding-top: 4px;
padding-bottom: 4px;
}
.navbar-action-group {
border: 1px solid #f0f0f0;
border-radius: 20px;
overflow: hidden;
}
.navbar-action_item {
padding: 3px 0;
color: #333;
}
.navbar-action-group .navbar-action_item {
border-right: 1px solid #f0f0f0;
padding: 3px 14px;
}
.navbar-action-group .last {
border-right: none;
}
index.json:
{
"component": true,
"usingComponents": {
"ss-icon": "../icon/index"
}
}
ss-icon はカスタムアイコンコンポーネントであり、必要に応じて他のアイコンコンポーネントに置き換え可能です。
コンポーネントの使用方法:
例えば index.wxml でこのコンポーネントを使用する場合:
1. index.json でコンポーネントをインポート:
{
"usingComponents": {
"navbar": "/components/navbar/index"
}
}
2. index.wxml でコンポーネントを呼び出す:
<view class='view-page'>
<navbar page-name="ページ名"></navbar>
<view class='page-content'>
<!-- コンテンツ -->
</view>
</view>
最終的な表示結果は以下のようになります。
3. パラメータ一覧
| パラメータ | 説明 | 型 | 初期値 |
|---|---|---|---|
| page-name | ページ名 | String | -- |
| show-nav | 左側のアイコンボタンの表示 | Boolean | true |
| bg-color | ナビゲーション背景色 | String | #fff |
| icon-color | アイコン色 | String | #000 |
| custom-class | ナビゲーションスタイル |
GitHubリポジトリ:微信小程序カスタムナビゲーションバー