小程序中實現(xiàn)自定義頭部導航組件的詳細過程
在頁面中實現(xiàn)自定義頭部導航的組件,如果僅是單個頁面中需要自定義可在頁面的json文件中配置"navigationStyle": “custom”,如果是項目中所有頁面都想使用自定義的組件,可在app.json的window中全局配置"navigationStyle": “custom”。
先分析頭部導航的組成,可參考圖1

其組成主要包含兩部分:狀態(tài)欄、導航區(qū)域,下面分別說說這兩部分的高度如何獲取。
1、獲取狀態(tài)欄高度
對于不同的機型而言,狀態(tài)欄的高度是有所差異的,可通過wx.getSystemInfo來獲取,但需要注意的是該接口在基礎(chǔ)庫2.20.1后就停止維護,需要改用wx.getWindowInfo獲取。
(1)使用wx.getSystemInfo獲取示例代碼
wx.getSystemInfo({
success: (res) => {
this.setData({
statusBarHeight: res.statusBarHeight
})
}
})
(2)使用wx.getWindowInfo示例代碼
constres = wx.getWindowInfo()
this.setData({
statusBarHeight: res.statusBarHeight
})2、導航區(qū)域高度
(1)導航區(qū)域的高度可自己定義,但考慮到右側(cè)膠囊,為使得標題位置垂直居中,因而導航區(qū)域的高度實際也需要計算得出。其公式為:導航區(qū)域的高度 = 膠囊的高度 + 膠囊距離狀態(tài)欄的高度 * 2。
// 獲取菜單按鈕(右上角膠囊按鈕)的布局位置信息。坐標信息以屏幕左上角為原點。
const rect = wx.getMenuButtonBoundingClientRect()
console.log('右上角膠囊按鈕)布局', rect);
// 獲取菜單按鈕(右上角膠囊按鈕)的布局位置信息。坐標信息以屏幕左上角為原點。
const rect = wx.getMenuButtonBoundingClientRect()
console.log('右上角膠囊按鈕)布局', rect);
wx.getSystemInfo({
success: (res) => {
this.setData({
navBarHeight: rect.bottom - rect.top + (rect.top - res.statusBarHeight) * 2,
// navBarHeight: rect.height + (rect.top - res.statusBarHeight) * 2,
})
}
})(2)考慮到膠囊位置,因而導航欄區(qū)域可自定義的寬度需減去膠囊的寬度,使用padding-right的方式占用膠囊的寬,注意需要設(shè)置為box-sizing: border-box,懂得都懂。

// 獲取菜單按鈕(右上角膠囊按鈕)的布局位置信息。坐標信息以屏幕左上角為原點。
const rect = wx.getMenuButtonBoundingClientRect()
console.log('右上角膠囊按鈕)布局', rect);
wx.getSystemInfo({
success: (res) => {
this.setData({
innerPaddingRight: `padding-right:${res.windowWidth - rect.left}px`,
})
}
})(3)剩余的寬度你就可以自由發(fā)揮了。
以下是組件參考代碼
index.xml
<view class="weui-navigation-bar {{extClass}}">
<view class="status-bar" style="height: {{statusBarHeight}}px; color: {{color}}; background: {{background}}"></view>
<view class="weui-navigation-bar__inner" style="height: {{navBarHeight}}px; color: {{color}}; background: {{background}}; {{displayStyle}}; {{innerPaddingRight}}">
<view class='weui-navigation-bar__left' style="{{leftWidth}}">
<block wx:if="{{back}}">
<view class="navigation-bar__buttons" bindtap="back">
<view class="navigation-bar__button navigation-bar__btn_goback" hover-class="active"></view>
</view>
</block>
<block wx:else>
<slot name="left"></slot>
</block>
</view>
<view class='weui-navigation-bar__center'>
<view wx:if="{{loading}}" class="weui-navigation-bar__loading" aria-role="alert">
<view class="weui-loading" style="width:{{size.width}}rpx;height:{{size.height}}rpx;" aria-role="img" aria-label="加載中"></view>
</view>
<block wx:if="{{title}}">
<text>{{title}}</text>
</block>
<block wx:else>
<slot name="center"></slot>
</block>
</view>
<view class='weui-navigation-bar__right'>
<slot name="right"></slot>
</view>
</view>
</view>index.wxss
.weui-navigation-bar {
overflow: hidden;
color: rgba(0, 0, 0, .9);
width: 100vw;
}
.status-bar{
width: 100%;
}
.weui-navigation-bar__placeholder {
background: #f7f7f7;
position: relative;
}
.weui-navigation-bar__inner, .weui-navigation-bar__inner .weui-navigation-bar__left {
display: flex;
align-items: center;
flex-direction: row;
}
.weui-navigation-bar__inner {
position: relative;
padding-right: 95px;
width: 100vw;
box-sizing: border-box;
padding-top: env(safe-area-inset-top);
}
.weui-navigation-bar__inner .weui-navigation-bar__left {
position: relative;
width: 95px;
padding-left: 16px;
box-sizing: border-box;
}
.weui-navigation-bar__btn_goback_wrapper {
padding: 11px 18px 11px 16px;
margin: -11px -18px -11px -16px;
}
.weui-navigation-bar__inner .weui-navigation-bar__left .navigation-bar__btn_goback {
font-size: 12px;
width: 12px;
height: 24px;
background: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='24' viewBox='0 0 12 24'%3E %3Cpath fill-opacity='.9' fill-rule='evenodd' d='M10 19.438L8.955 20.5l-7.666-7.79a1.02 1.02 0 0 1 0-1.42L8.955 3.5 10 4.563 2.682 12 10 19.438z'/%3E%3C/svg%3E") no-repeat 50% 50%;
background-size: cover;
}
.weui-navigation-bar__inner .weui-navigation-bar__center {
font-size: 17px;
text-align: center;
position: relative;
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-weight: bold;
}
@media(prefers-color-scheme: dark) {
.weui-navigation-bar {
color: hsla(0, 0%, 100%, .8);
}
.weui-navigation-bar__inner {
background-color: #1f1f1f;
}
}index.js
Component({
options: {
multipleSlots: true // 在組件定義時的選項中啟用多slot支持
},
/**
* 組件的屬性列表
*/
properties: {
extClass: {
type: String,
value: ''
},
title: {
type: String,
value: ''
},
background: {
type: String,
value: '#fff'
},
color: {
type: String,
value: '#000'
},
back: {
type: Boolean,
value: true
},
loading: {
type: Boolean,
value: false
},
animated: {
// 顯示隱藏的時候opacity動畫效果
type: Boolean,
value: true
},
show: {
// 顯示隱藏導航,隱藏的時候navigation-bar的高度占位還在
type: Boolean,
value: true,
observer: '_showChange'
},
// back為true的時候,返回的頁面深度
delta: {
type: Number,
value: 1
}
},
/**
* 組件的初始數(shù)據(jù)
*/
data: {
displayStyle: '',
statusBarHeight: 20
},
attached() {
// 獲取菜單按鈕(右上角膠囊按鈕)的布局位置信息。坐標信息以屏幕左上角為原點。
const rect = wx.getMenuButtonBoundingClientRect()
// console.log('右上角膠囊按鈕)布局', rect);
wx.getSystemInfo({
success: (res) => {
this.setData({
innerPaddingRight: `padding-right:${res.windowWidth - rect.left}px`,
leftWidth: `width:${res.windowWidth - rect.left}px`,
// navBarHeight: rect.bottom + rect.top - res.statusBarHeight, //84px
navBarHeight: rect.bottom - rect.top + (rect.top - res.statusBarHeight) * 2, //40px
statusBarHeight: res.statusBarHeight //44px
})
}
})
},
/**
* 組件的方法列表
*/
methods: {
_showChange(show) {
const animated = this.data.animated
let displayStyle = ''
if (animated) {
displayStyle = `opacity: ${show ? '1' : '0'};transition: opacity 0.5s;`
} else {
displayStyle = `display: ${show ? '' : 'none'}`
}
this.setData({
displayStyle
})
},
back() {
const data = this.data
if (data.delta) {
wx.navigateBack({
delta: data.delta
})
}
this.triggerEvent('back', { delta: data.delta }, {})
}
}
})index.json
{
"component": true,
"usingComponents": {}
}在頁面中使用該組件
page.json
{
"usingComponents": {
"zxm-navigation-bar": "/components/zxm-navigation-bar" //該成你所放組件的路徑喲
},
"navigationStyle": "custom",
"disableScroll": true
}page.wxml
<view> <zxm-navigation-bar title="標題"></zxm-navigation-bar> </view>
代碼也可前往這里下載
到此這篇關(guān)于小程序中實現(xiàn)自定義頭部導航組件的詳細過程的文章就介紹到這了,更多相關(guān)小程序自定義頭部導航組件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
快速獲取/設(shè)置iframe內(nèi)對象元素的幾種js實現(xiàn)方法
下面小編就為大家?guī)硪黄焖佾@取/設(shè)置iframe內(nèi)對象元素的幾種js實現(xiàn)方法。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-05-05
JavaScript如何處理移動端拍攝圖片旋轉(zhuǎn)問題
這篇文章主要告訴大家JavaScript如何處理移動端拍攝圖片旋轉(zhuǎn)問題,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-11-11
js將json格式的對象拼接成復雜的url參數(shù)方法
下面小編就為大家?guī)硪黄猨s將json格式的對象拼接成復雜的url參數(shù)方法。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-05-05
Javascript打印網(wǎng)頁部分內(nèi)容的腳本
有時候我們只需要打印部分內(nèi)容,因為現(xiàn)在的頁面中廣告和一些相關(guān)內(nèi)容很多,所有用下面的方法,就可以了2008-11-11
js中requestAnimationFrame()解讀與使用示例
requestAnimationFrame()是JavaScript中用于創(chuàng)建高效、流暢動畫的核心方法,它與瀏覽器的重繪過程同步,確保每次動畫更新都與顯示器刷新率同步,下面就來一起了解一下2024-09-09
JS判斷輸入的字符串是否是數(shù)字的方法(正則表達式)
下面小編就為大家?guī)硪黄狫S判斷輸入的字符串是否是數(shù)字的方法(正則表達式)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-11-11

