文末貼了自定義導航欄的源代碼,不想看分析的能夠直接到最後提取。javascript
// 僅須要傳入導航欄的標題 <navigation title="自定義導航欄"></navigation> // 支持導航欄樣式配置化 <navigation title="自定義導航欄" titleColor="white" backgroundColor="none"></navigation> 複製代碼
自定義導航欄高度能夠拆解成系統導航欄的高度 + 小程序導航欄的高度,其中系統導航欄高度能夠經過 API
獲取,小程序導航欄高度默認爲 50px
css
// 根據不一樣機型動態計算導航欄理想高度 computeHeight() { wx.getSystemInfo({ success: (res) => { this.setData({ statusBarHeight: res.statusBarHeight, navigationBarHeight: 50 + res.statusBarHeight, }); }, }); } 複製代碼
核心邏輯:當頁面堆棧超過1時,則顯示返回按鈕,不然不顯示。html
ready() { this.setData({ showBack: getCurrentPages().length > 1 }); } 複製代碼
有時候須要攔截返回來處理一些邏輯,好比彈出挽留彈窗等,則能夠阻止默認的返回事件java
// 外部組件使用 <navigation title="攔截返回" noBack bindback="onBack"/> // 組件內部返回事件邏輯 back() { if (getCurrentPages().length > 0 && !this.data.noBack) { getCurrentPages().length > 1 && wx.navigateBack(); } else { this.triggerEvent('back') } } 複製代碼
在某些場景下,雙擊導航欄須要返回頂部或者進行刷新web
// 點擊導航欄,進入雙擊邏輯判斷 onClick(e) { if (this.data.clickNum === 0) { this.setData({ clickNum: 1, clickTimer: setTimeout(() => { this.resetClick() }, 300) }); } else { this.triggerEvent('doubleClick'); this.resetClick(); } }, resetClick() { clearTimeout(this.data.clickTimer) this.setData({ clickNum: 0, clickTimer: null }); } 複製代碼
navigation.jsonjson
{
"component": true
}
複製代碼
navigation.wxml,其中返回圖標和首頁圖標未提供小程序
<!-- 導航欄佔位符,高度與導航欄高度一致 --> <view class="placeholder" wx:if="{{placeholder}}" style="height: {{navigationBarHeight}}px;"/> <!-- 導航欄 --> <view bindtap="onClick" class="navigation-wrap" style="color: {{titleColor}};height: {{navigationBarHeight}}px;line-height:{{navigationBarLineHeight}}px;background: {{backgroundColor}};" > <!-- 返回按鈕 --> <view class="back-wrap" catchtap="back"> <image wx:if="{{showBack}}" src="/assets/images/navigation/navigation-back-{{titleColor == 'white' ? 'white' : 'black'}}.svg" /> <image class="icon-home" wx:if="{{!showBack && showHome}}" src="/assets/images/navigation/navigation-home-{{titleColor == 'white' ? 'white' : 'black'}}.svg" /> </view> <!-- 導航欄標題 --> <view class="title">{{title}}</view> <!-- 導航欄右邊返回按鈕佔位符,寬度與返回按鈕寬度一致 --> <view class="back-wrap back-slot"></view> </view> 複製代碼
navigation.jsbash
Component({ properties: { title: { /* 標題 */ type: String, value: '' }, titleColor: { /* 標題顏色 */ type: String, value: 'black' }, noBack: { /* 是否攔截返回 */ type: Boolean, value: false }, showHome: { /* 是否顯示首頁按鈕 */ type: Boolean, value: false }, backgroundColor: { /* 背景 */ type: String, value: '#ffffff' }, placeholder: { /* 是否須要佔位 */ type: Boolean, value: true }, }, data: { showBack: false, // 是否顯示返回按鈕 statusBarHeight: 0, // 頂部系統狀態條高度 navigationBarHeight: 0, // 導航欄高度 navigationBarLineHeight: 0, // 導航欄行高 navigationBarBackgroundHeight: 0, // 導航欄背景高度 clickNum: 0, clickTimer: null, }, ready() { this.computeHeight(); this.setData({ showBack: getCurrentPages().length > 1 }); }, methods: { // 點擊返回按鈕,默認返回上一頁,若是返回被攔截則只上報一個back事件 back() { if (getCurrentPages().length > 0 && !this.data.noBack) { getCurrentPages().length > 1 && wx.navigateBack(); } else { this.triggerEvent('back') } }, // 根據不一樣機型動態計算導航欄理想高度 computeHeight() { wx.getSystemInfo({ success: (res) => { this.setData({ statusBarHeight: res.statusBarHeight, navigationBarHeight: 50 + res.statusBarHeight, navigationBarLineHeight: 44 + res.statusBarHeight * 2, }); this.triggerEvent('updateNavigationHeight', this.data.navigationBarHeight); this.triggerEvent('updateStatusBarHeight', this.data.statusBarHeight); }, }); }, // 點擊導航欄,進入雙擊邏輯判斷 onClick(e) { if (this.data.clickNum === 0) { this.setData({ clickNum: 1, clickTimer: setTimeout(() => { this.resetClick() }, 300) }); } else { this.triggerEvent('doubleClick'); this.resetClick(); } }, resetClick() { clearTimeout(this.data.clickTimer) this.setData({ clickNum: 0, clickTimer: null }); }, }, }); 複製代碼
navigation.wxssmarkdown
<style lang="scss"> .placeholder { width: 100%; } .navigation-wrap { background: white; text-align: center; font-size: 36rpx; overflow: hidden; box-sizing: border-box; width: 100%; position: fixed; left: 0; top: 0; z-index: 1000; display: flex; .back-wrap { text-align: left; padding-left: 32rpx; box-sizing: border-box; width: 80rpx; height: 100%; image { width: 16rpx; height: 28rpx; } .icon-home { width: 40rpx; height: 36rpx; } } .title { flex: 1; height: 100%; padding:0 60px; overflow:hidden; display:-webkit-box; word-break:break-all; -webkit-line-clamp: 1; text-overflow:ellipsis; -webkit-box-orient: vertical; } } </style> 複製代碼
<!-- 基礎用法 --> <navigation title="自定義導航欄"/> <!-- 透明背景 + 不佔任何空間 --> <navigation title="自定義導航欄" backgroundColor="none" placeholder="{{false}}"/> <!-- 黑夜模式:白色標題 + 黑色背景 --> <navigation title="自定義導航欄" titleColor="#FFFFFF" backgroundColor="#000000"/> <!-- 攔截返回事件 --> <navigation title="自定義導航欄" noback bindback="onBack"/> <!-- 顯示首頁圖標 --> <navigatoin title="自定義導航欄" showHome/> <!-- 雙擊刷新頁面 --> <navigation title="自定義導航欄" binddoubleClick="onRefresh"/> 複製代碼