微信小程序自定義導(dǎo)航欄(模板化)
前段時(shí)間寫過(guò)一篇關(guān)于微信小程序自定義導(dǎo)航欄的自定義組件,但是對(duì)于分享頁(yè)有一定的bug
這次用模板化又搞了一遍 優(yōu)化了下Android與IOS 顯示更接近微信原生的導(dǎo)航欄,以及修復(fù)分享頁(yè)面不顯示返回首頁(yè)按鈕
如果大家不習(xí)慣模板化的話可以 針對(duì)自己的需求拿以前封裝的組件化做一些修改
微信小程序自定義導(dǎo)航欄(組件化)
CustomNavBar.wxml
<template name="CustomNavBar">
<block wx:if="{{ showNavBar }}">
<!-- 自定義導(dǎo)航欄懸浮時(shí),卡空行 -->
<block wx:if="{{ needFixed }}">
<view style="position: relative; width: 100%; height: {{ navHeight }}px;"></view>
</block>
<view class="custom-navbar-con relative {{ iOS ? ' ios ' : ' android ' }}" style="height: {{ navHeight }}px; {{ needFixed ? 'position: fixed; top: 0;' : '' }}">
<view class="custom-navbar-statusbar-con relative" style="height: {{ statusBarHeight }}px;"></view>
<view class="custom-navbar-content relative" style="height: {{ navHeight - statusBarHeight }}px;">
<!-- iOS端的導(dǎo)航欄顯示方式 -->
<block wx:if="{{ navTitle && navTitle.length > 0 }}">
<view class="custom-navbar-title ios">{{ navTitle }}</view>
</block>
<block wx:if="{{ showLeftMenu }}">
<view class="custom-navbar-left-menu-con clearfix" style="top: {{ navRightMenuRect.top - statusBarHeight - 1 }}px; left: {{ winWidth - navRightMenuRect.right }}px; height: {{ navRightMenuRect.height + 2 }}px;">
<block wx:if="{{ showBackBtn }}">
<view class="custom-navbar-icon-btn pull-left back" style="height: {{ navRightMenuRect.height }}px" bindtap="customNavBarBack">
<image class="icon" src="../../image/icon-nav-back.png" mode="aspectFit" style="width: {{ navRightMenuRect.height }}px;" />
<text class="text"></text>
</view>
</block>
<block wx:if="{{ showHomeBtn }}">
<view class="custom-navbar-icon-btn pull-left home" style="height: {{ navRightMenuRect.height }}px" bindtap="customNavBarBackToHome">
<image class="icon" src="../../image/icon-nav-home.png" mode="aspectFit" style="width: {{ navRightMenuRect.height }}px;" />
<text class="text"></text>
</view>
</block>
<!-- android端的導(dǎo)航欄顯示方式 -->
<block wx:if="{{ navTitle && navTitle.length > 0 }}">
<view class="custom-navbar-title android pull-left" style="line-height: {{ navRightMenuRect.height - 2 }}px;">{{ navTitle }}</view>
</block>
</view>
</block>
</view>
</view>
</block>
</template>
CustomNavBar.wxss
.custom-navbar-con { position: relative; width: 100%; background-color: white; z-index: 9999; }
.custom-navbar-con .custom-navbar-statusbar-con { width: 100%; }
.custom-navbar-con .custom-navbar-content { width: 100%; }
.custom-navbar-con .custom-navbar-left-menu-con { position: absolute; }
.custom-navbar-con .custom-navbar-left-menu-con .custom-navbar-icon-btn { height: 100%; border-radius: 200px; border: 1px solid rgba(220, 220, 220, 0.6); }
.custom-navbar-con .custom-navbar-left-menu-con .custom-navbar-icon-btn .icon { height: 90%; margin-top: 2.5%; }
.custom-navbar-con .custom-navbar-left-menu-con .custom-navbar-icon-btn .text { font-size: 27rpx; }
.custom-navbar-con .custom-navbar-left-menu-con .custom-navbar-icon-btn.back { border: none; }
.custom-navbar-con .custom-navbar-left-menu-con .custom-navbar-icon-btn.back~.custom-navbar-icon-btn.home { margin-left: 10rpx; }
.custom-navbar-con .custom-navbar-left-menu-con .custom-navbar-icon-btn.switch-shop { padding-left: 5px; padding-right: 25rpx; }
.custom-navbar-con.ios .custom-navbar-title.android { display: none; }
.custom-navbar-con.android .custom-navbar-title.ios { display: none; }
.custom-navbar-con .custom-navbar-title.ios { font-weight: bold; text-align: center; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); -webkit-transform: translate(-50%, -50%); }
.custom-navbar-con .custom-navbar-title.android { padding-left: 30rpx; }```
CustomNavBar.js
```javascript
module.exports = function(PageInstance) {
let App = getApp()
let _tplData = {
_CustomNavBar_: {
navRightMenuRect: App.NavRightMenuRect,
navRightMenuCenterY: App.NavRightMenuCenterY,
statusBarHeight: App.StatusBarHeight,
winWidth: App.WinWidth,
winHeight: App.WinHeight,
iOS: App.iOS,
navTitle: '', // 當(dāng)前只合適短標(biāo)題,如需長(zhǎng)標(biāo)題,建議隱藏自定義導(dǎo)航欄,自定義展示
navHeight: App.CustomNavHeight,
needFixed: false,
showNavBar: !App.NavRightMenuRect ? false : true,
showLeftMenu: true,
showBackBtn: true,
showHomeBtn: false
}
}
let _tplMethods = {
customNavBarBack() {
wx.navigateBack()
},
customNavBarBackToHome() {
let url = '/pages/index/index'
wx.reLaunch({
url: url
})
}
}
let isIndexPage = !!(PageInstance.route == 'pages/index/index')
let pages = getCurrentPages()
if (pages.length == 1) {
_tplData._CustomNavBar_.showBackBtn = false
_tplData._CustomNavBar_.showHomeBtn = !isIndexPage
}
// 每個(gè)頁(yè)面 可單獨(dú)配置自定義導(dǎo)航欄
if (PageInstance.data.CustomNavBarConfig) {
Object.assign(_tplData._CustomNavBar_, PageInstance.data.CustomNavBarConfig)
}
// !!!! 最后執(zhí)行
// 當(dāng)無(wú)法獲取到右上角按鈕膠囊的布局位置時(shí),強(qiáng)制設(shè)置自定義導(dǎo)航欄為隱藏狀態(tài)
if (!App.NavRightMenuRect) {
_tplData._CustomNavBar_.showNavBar = false
}
Object.assign(PageInstance, _tplMethods)
PageInstance.setData(_tplData)
return this
}
app.js的配置
// 自定義導(dǎo)航欄
import CustomNavBar from './template/CustomNavBar/CustomNavBar';
App({
//自定義 模板式 組件
CustomNavBar,
// 系統(tǒng)信息
WinWidth: 0,
WinHeight: 0,
StatusBarHeight: 0,
PixelRatio: 1,
SystemFullName: '',
SystemVersion: '',
SystemSDKVersion: '',
//自定義導(dǎo)航欄相關(guān)
NavRightMenuRect: null,
NavRightMenuCenterY: 0,
CustomNavHeight: 0,
onLaunch: function (options) {
let self = this
let systemInfo = wx.getSystemInfoSync()
self.iOS = systemInfo.platform === 'ios'
self.isDebug = systemInfo.platform === 'devtools'
if (self.isDebug) {
// 單純?yōu)榱嗽陂_(kāi)發(fā)工具下調(diào)試 自定義導(dǎo)航欄
// 開(kāi)發(fā)工具下不存在App版本號(hào)的區(qū)分
systemInfo.version = '7.0.0'
}
self.WinWidth = systemInfo.windowWidth
self.WinHeight = systemInfo.windowHeight
self.StatusBarHeight = systemInfo.statusBarHeight
// 部分小程序庫(kù)版本沒(méi)有返回狀態(tài)欄高度
if (!self.StatusBarHeight) {
self.StatusBarHeight = 20
}
self.PixelRatio = Math.max(systemInfo.pixelRatio, 2)
self.SystemFullName = systemInfo.system
self.SystemVersion = systemInfo.version
self.SystemSDKVersion = systemInfo.SDKVersion
// app.json全局配置的自定義導(dǎo)航欄的話,客戶端需求版本為6.6.0
// 每個(gè)頁(yè)面 單獨(dú)配置的自定義導(dǎo)航欄的話,客戶端需求版本為7.0.0
// wx.getMenuButtonBoundingClientRect方法,要求基礎(chǔ)庫(kù)版本為2.1.0
if (self.compareVersion(self.SystemVersion, '6.6.0') >= 0) {
// 官方的6.6.0版本以上客戶端,最低基礎(chǔ)庫(kù)版本為1.9.4
// 6.6.0以上且[1.9.4 - 2.1.0]范圍內(nèi)的機(jī)型無(wú)法使用wx.getMenuButtonBoundingClientRect
// 所以手動(dòng)寫死非全面屏手機(jī)的適配膠囊布局位置
self.NavRightMenuRect = {
top: 26,
bottom: 58,
right: self.WinWidth - 10,
width: 87,
height: 32
}
// 如果系統(tǒng)信息返回的狀態(tài)欄高度大于20,認(rèn)為是全面屏手機(jī)
if (self.StatusBarHeight > 20) {
self.NavRightMenuRect.top = 50
self.NavRightMenuRect.bottom = 82
}
// 2019年08月21日22:09:22
// 微信小程序庫(kù)出現(xiàn)bug,導(dǎo)致部分機(jī)型wx.getMenuButtonBoundingClientRect無(wú)返回值
// 所以在這之前先默認(rèn)寫死一個(gè)NavRightMenuRect,防止全局的自定義導(dǎo)航欄已經(jīng)隱藏了但是無(wú)法顯示自定義導(dǎo)航欄
// 詳見(jiàn)https://developers.weixin.qq.com/community/develop/doc/00062238d78e880aedd88b72351c00
if (wx.getMenuButtonBoundingClientRect) {
let NavRightMenuRect = wx.getMenuButtonBoundingClientRect()
self.NavRightMenuRect = {
top: NavRightMenuRect.top,
bottom: NavRightMenuRect.bottom,
right: NavRightMenuRect.right,
width: NavRightMenuRect.width,
height: NavRightMenuRect.height
}
}
self.NavRightMenuCenterY = self.NavRightMenuRect.top + self.NavRightMenuRect.height / 2
self.CustomNavHeight = self.NavRightMenuRect.bottom + (self.NavRightMenuRect.top - self.StatusBarHeight)
} else {
self.NavRightMenuRect = null
self.CustomNavHeight = 0
}
},
// 比較兩個(gè)版本號(hào)
compareVersion (v1, v2) => {
v1 = v1.split('.')
v2 = v2.split('.')
const len = Math.max(v1.length, v2.length)
while (v1.length < len) {
v1.push('0')
}
while (v2.length < len) {
v2.push('0')
}
for (let i = 0; i < len; i++) {
const num1 = parseInt(v1[i])
const num2 = parseInt(v2[i])
if (num1 > num2) {
return 1
} else if (num1 < num2) {
return -1
}
}
return 0
}
}),
假如在index 頁(yè)面引用
index.wxml
<!-- 自定義NavBar -->
<import src="../../template/CustomNavBar/CustomNavBar.wxml" />
<template is="CustomNavBar" data="{{ ..._CustomNavBar_ }}"></template>
index.js
onLoad: function(options) {
new App.CustomNavBar(this)
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
js Html結(jié)構(gòu)轉(zhuǎn)字符串形式顯示代碼
js Html結(jié)構(gòu)轉(zhuǎn)字符串形式顯示代碼,需要的朋友可以參考下。2011-11-11
微信小程序如何修改本地緩存key中單個(gè)數(shù)據(jù)的詳解
這篇文章主要介紹了微信小程序如何修改本地緩存key中單個(gè)數(shù)據(jù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
非常好用的JsonToString 方法 簡(jiǎn)單實(shí)例
這篇文章介紹了非常好用的JsonToString簡(jiǎn)單實(shí)例,有需要的朋友可以參考一下2013-07-07
微信小程序?qū)崿F(xiàn)購(gòu)物車代碼實(shí)例詳解
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)購(gòu)物車代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-08-08
JavaScript通過(guò)改變文字透明度實(shí)現(xiàn)的文字閃爍效果實(shí)例
這篇文章主要介紹了JavaScript通過(guò)改變文字透明度實(shí)現(xiàn)的文字閃爍效果,結(jié)合完整實(shí)例形式分析了javascript基于定時(shí)器周期性動(dòng)態(tài)修改頁(yè)面元素屬性的相關(guān)操作技巧,需要的朋友可以參考下2017-04-04

