uniapp微信小程序自定義導(dǎo)航欄的全過程
前言
相信很多小伙伴在使用uniapp進(jìn)行多端開發(fā)的時(shí)候呢,在面對(duì)一些奇葩的業(yè)務(wù)需求的時(shí)候,uniapp給我們提供的默認(rèn)導(dǎo)航欄已經(jīng)不能滿足我們的業(yè)務(wù)需求了,這個(gè)時(shí)候就需要我們自己自定義導(dǎo)航欄使用啦。
當(dāng)然uniapp也給我們提供了很多的自定義導(dǎo)航欄的插件供大家使用,今天也給大家分享一個(gè)我自己寫的導(dǎo)航欄啦,希望大家多多指點(diǎn)
首先我們?cè)谧远x導(dǎo)航欄的時(shí)候,我們需要知道頭部的導(dǎo)航欄有哪幾部分組成,那么我們以微信小程序?yàn)槔?/p>
可以看到在微信小程序中,我們的頭部導(dǎo)航欄其實(shí)受到右上角膠囊的限制比較大,這個(gè)時(shí)候我們自定義的導(dǎo)航欄,需要做到標(biāo)題于膠囊水平對(duì)齊,那其實(shí)這個(gè)時(shí)候整個(gè)頭部其實(shí)主要又:狀態(tài)欄的高度+標(biāo)題欄的高度組成。
狀態(tài)欄的高度我們可以通過uni.getSystemInfoSync().statusBarHeight
來獲取。
那么標(biāo)題欄的高度我們?cè)趺传@取呢?
其實(shí)要想定義標(biāo)題欄的高度,我們需要知道這個(gè)膠囊的位置,在小程序中我們可以使用wx.getMenuButtonBoundingClientRect()獲取關(guān)于膠囊的信息
獲取到的膠囊的top,left,right分別對(duì)應(yīng)膠囊的上邊界,左邊界,右邊界相對(duì)于屏幕左上角的起點(diǎn)的位置,所以我們是不是可以用(膠囊上邊界距離頂部的距離 - 狀態(tài)欄的高度)*2+膠囊的高度,就是標(biāo)題欄的高度呢?然后再在標(biāo)題欄里面添加一個(gè)文本區(qū)讓他的高度等于膠囊的高度,實(shí)現(xiàn)flex布局的上下居中是不是就搞定了呢?
以上呢其實(shí)針對(duì)小程序平臺(tái)的導(dǎo)航欄講解,那么既然使用uniapp,就會(huì)考慮到多端情況
那么其實(shí)我們使用uniapp獲取到的狀態(tài)欄在h5,小程序和app原生都是有效的,h5網(wǎng)頁中一般我們都是直接采用瀏覽器內(nèi)核給我們內(nèi)置的網(wǎng)頁導(dǎo)航欄,就是一個(gè)頭部,沒有過多的要求,而且瀏覽器不同,給我們提供的頭部導(dǎo)航也不一樣。
而對(duì)于app端,我們沒有了像微信小程序中那種讓人心煩的膠囊之后,我們只需要知道狀態(tài)欄的高度,然后加上自己業(yè)務(wù)需求的標(biāo)題欄樣式和標(biāo)題欄高度就行啦
所以我們?cè)谶M(jìn)行自定義導(dǎo)航欄封裝的時(shí)候就要對(duì)代碼進(jìn)行條件編譯啦。那么我這里呢是把微信小程序做了單獨(dú)的處理,微信小程序之外的平臺(tái)看作是統(tǒng)一狀態(tài)
獻(xiàn)上源碼:
首先我們把獲取設(shè)備信息的代碼封裝到一個(gè)統(tǒng)一的js文件里面,這樣方便我們?cè)诮M件中獲取也方便我們?cè)陧撁嬷蝎@取。
/** * 此js文件管理關(guān)于當(dāng)前設(shè)備的機(jī)型系統(tǒng)信息 */ const systemInfo = function() { /****************** 所有平臺(tái)共有的系統(tǒng)信息 ********************/ // 設(shè)備系統(tǒng)信息 let systemInfomations = uni.getSystemInfoSync() // 機(jī)型適配比例系數(shù) let scaleFactor = 750 / systemInfomations.windowWidth // 當(dāng)前機(jī)型-屏幕高度 let windowHeight = systemInfomations.windowHeight * scaleFactor //rpx // 當(dāng)前機(jī)型-屏幕寬度 let windowWidth = systemInfomations.windowWidth * scaleFactor //rpx // 狀態(tài)欄高度 let statusBarHeight = (systemInfomations.statusBarHeight) * scaleFactor //rpx // 導(dǎo)航欄高度 注意:此導(dǎo)航欄高度只針對(duì)微信小程序有效 其他平臺(tái)如自定義導(dǎo)航欄請(qǐng)使用:狀態(tài)欄高度+自定義文本高度 let navHeight = 0 //rpx // console.log(windowHeight,'哈哈哈哈哈'); /****************** 微信小程序頭部膠囊信息 ********************/ // #ifdef MP-WEIXIN const menuButtonInfo = wx.getMenuButtonBoundingClientRect() // 膠囊高度 let menuButtonHeight = menuButtonInfo.height * scaleFactor //rpx // 膠囊寬度 let menuButtonWidth = menuButtonInfo.width * scaleFactor //rpx // 膠囊上邊界的坐標(biāo) let menuButtonTop = menuButtonInfo.top * scaleFactor //rpx // 膠囊右邊界的坐標(biāo) let menuButtonRight = menuButtonInfo.right * scaleFactor //rpx // 膠囊下邊界的坐標(biāo) let menuButtonBottom = menuButtonInfo.bottom * scaleFactor //rpx // 膠囊左邊界的坐標(biāo) let menuButtonLeft = menuButtonInfo.left * scaleFactor //rpx // 微信小程序中導(dǎo)航欄高度 = 膠囊高度 + (頂部距離 - 狀態(tài)欄高度) * 2 navHeight = menuButtonHeight + (menuButtonTop - statusBarHeight) * 2 // #endif // #ifdef MP-WEIXIN return { scaleFactor, windowHeight, windowWidth, statusBarHeight, menuButtonHeight, menuButtonWidth, menuButtonTop, menuButtonRight, menuButtonBottom, menuButtonLeft, navHeight } // #endif // #ifndef MP-WEIXIN return { scaleFactor, windowHeight, windowWidth, statusBarHeight } // #endif } export { systemInfo }
然后我們定義一個(gè)導(dǎo)航欄組件
/* * 注意: * 1、在傳入寬度或者高度時(shí),如果是Number數(shù)據(jù),傳入的值為px大小,無需帶單位,組件自動(dòng)計(jì)算 * 2、在使用此導(dǎo)航欄時(shí),建議傳入U(xiǎn)I規(guī)定的導(dǎo)航欄高度,此高度只針對(duì)除微信小程序的其他平臺(tái)有效,微信小程序的導(dǎo)航欄高度,組件自計(jì)算 */ <template> <view> <!-- 微信小程序頭部導(dǎo)航欄 --> <!-- #ifdef MP-WEIXIN --> <view class="wx-head-mod" :style="{height:navHeight+'rpx',backgroundColor:navBackgroundColor}"> <view class="wx-head-mod-nav" :style="{height:navigationBarHeight+'rpx',top:statusBarHeight+'rpx'}"> <view class="wx-head-mod-nav-content" :style="{height:customHeight+'rpx',justifyContent:textAlign === 'center'?'center':'left'}"> <!-- 文本區(qū) --> <view class="wx-head-mod-nav-content-mian" :style="{width:navTextWidth,lineHeight:customHeight + 'rpx',paddingLeft:textPaddingLeft*scaleFactor+'rpx',fontSize:fontSize*scaleFactor+'rpx',fontWeight:fontWeight,color:titleColor}"> {{textContent}} </view> <!-- 返回按鈕 --> <view class="wx-head-mod-nav-content-back" :style="{display:isBackShow?'flex':'none'}" @click="backEvent"> <view class="wx-head-mod-nav-content-back-img" :style="{width:backImageWidth*scaleFactor+'rpx',height:backImageHeight*scaleFactor+'rpx'}"> <image :src="backImageUrl" mode="" style="width: 100%;height: 100%;"></image> </view> </view> </view> </view> </view> <!-- #endif --> <!-- 除微信小程序之外的其他設(shè)備 --> <!-- #ifndef MP-WEIXIN --> <view class="other-head-mod" :style="{height:navHeightValue*scaleFactor+statusBarHeight+'rpx',backgroundColor:navBackgroundColor}"> <view class="other-head-mod-mian" :style="{height:navHeightValue*scaleFactor+'rpx',justifyContent:textAlign === 'center'?'center':'left'}"> <!-- 返回按鈕 --> <view class="other-head-mod-mian-back" v-show="isBackShow" @click="backEvent"> <view class="other-head-mod-mian-back-img" :style="{width:backImageWidth*scaleFactor+'rpx',height:backImageHeight*scaleFactor+'rpx'}"> <image :src="backImageUrl" mode="" style="width: 100%;height: 100%;"></image> </view> </view> <!-- 標(biāo)題 --> <view class="other-head-mod-mian-title" :style="{width:windowWidth - 184+'rpx',lineHeight:navHeightValue*scaleFactor+'rpx', paddingLeft:textPaddingLeft*scaleFactor+'rpx',fontSize:fontSize*scaleFactor+'rpx', fontWeight:fontWeight,color:titleColor}"> {{textContent}} </view> </view> </view> <!-- #endif --> </view> </template> <script> const app = getApp() import {systemInfo} from '@/common/system-info.js' export default { name: "HeadView", props: { // 文本區(qū)域位置 left:左 center:中 textAlign: { type: String, default: 'center' }, // 文本區(qū)內(nèi)容 textContent: { type: String, default: '哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈就啊哈哈好借好還' }, // 文本區(qū)離左邊的距離 textPaddingLeft: { type: Number, default: 16 }, // 是否需要返回按鈕 isBackShow: { type: Boolean, default: true }, // 文本區(qū)字體大小 fontSize: { type: Number, default: 20 //px }, // 文本區(qū)字體粗細(xì) fontWeight: { type: Number, default: 700 }, // 文本區(qū)返回按鈕圖片寬 backImageWidth: { type: Number, default: 12 //px }, // 文本區(qū)返回按鈕圖片高 backImageHeight: { type: Number, default: 24 //px }, // 返回按鈕圖標(biāo)路徑 backImageUrl: { type: String, default: '/static/backImage.svg' }, // 導(dǎo)航欄整體背景顏色 navBackgroundColor: { type: String, default: '#2476F9' }, // 標(biāo)題字體顏色 titleColor: { type: String, default: '#ffffff', }, /******** h5端,app端需要傳入自定義導(dǎo)航欄高度 *******/ navHeightValue: { type: Number, default: 44 //px } }, computed: { // 文本區(qū)寬度 navTextWidth() { if (this.textAlign === 'center') { return (this.windowWidth - (this.windowWidth - this.menubarLeft) * 2) + 'rpx' } else { return this.menubarLeft + 'rpx' } }, // 文本區(qū)paddingLeft textPaddingleft() { if (this.textAlign === 'center') { return '0' } else { return this.textPaddingLeft + 'rpx' } } }, data() { return { statusBarHeight: app.globalData.statusBarHeight, //狀態(tài)欄高度 navHeight: app.globalData.navHeight, //頭部導(dǎo)航欄總體高度 navigationBarHeight: app.globalData.navigationBarHeight, //導(dǎo)航欄高度 customHeight: app.globalData.customHeight, //膠囊高度 scaleFactor: app.globalData.scaleFactor, //比例系數(shù) menubarLeft: app.globalData.menubarLeft, //膠囊定位的左邊left windowWidth: app.globalData.windowWidth * app.globalData.scaleFactor }; }, methods: { backEvent() { uni.navigateBack({ delta: 1 }) } }, created() { /* 獲取設(shè)備信息 */ const SystemInfomations = systemInfo() /* 通用平臺(tái) */ this.statusBarHeight = SystemInfomations.statusBarHeight //狀態(tài)欄高度 this.scaleFactor = SystemInfomations.scaleFactor //比例系數(shù) this.windowWidth = SystemInfomations.windowWidth //當(dāng)前設(shè)備的屏幕寬度 /* 微信小程序平臺(tái) */ // #ifdef MP-WEIXIN this.navHeight = SystemInfomations.navHeight + SystemInfomations.statusBarHeight //頭部導(dǎo)航欄總高度 this.navigationBarHeight = SystemInfomations.navHeight //頭部導(dǎo)航欄高度 this.customHeight = SystemInfomations.menuButtonHeight //膠囊高度 this.menubarLeft = SystemInfomations.menuButtonLeft //膠囊左邊界距離左上角的距離 // #endif } } </script> <style> /* #ifdef MP-WEIXIN */ .wx-head-mod { box-sizing: border-box; width: 100%; position: fixed; top: 0; left: 0; } .wx-head-mod-nav { box-sizing: border-box; width: 100%; position: absolute; left: 0; display: flex; justify-content: center; align-items: center; } .wx-head-mod-nav-content { box-sizing: border-box; width: 100%; display: flex; justify-content: left; align-items: center; position: relative; } /* 文本區(qū) */ .wx-head-mod-nav-content-mian { box-sizing: border-box; height: 100%; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; } /* 返回按鈕 */ .wx-head-mod-nav-content-back { box-sizing: border-box; width: 60rpx; height: 100%; /* background-color: aqua; */ position: absolute; top: 0; left: 32rpx; display: flex; align-items: center; justify-content: left; } .wx-head-mod-nav-content-back-img { box-sizing: border-box; } /* #endif */ /* #ifndef MP-WEIXIN */ .other-head-mod { box-sizing: border-box; width: 100%; position: fixed; top: 0; left: 0; } .other-head-mod-mian { box-sizing: border-box; width: 100%; display: flex; align-items: center; justify-content: left; position: absolute; left: 0; bottom: 0; } /* 返回按鈕 */ .other-head-mod-mian-back { box-sizing: border-box; height: 100%; width: 60rpx; position: absolute; left: 32rpx; top: 0; display: flex; align-items: center; } /* 標(biāo)題 */ .other-head-mod-mian-title { box-sizing: border-box; height: 100%; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; } /* #endif */ </style>
組件使用:
引入組件:
import HeadNav from '@/components/HeadNav.vue'
組冊(cè)組件:
components:{ HeadNav },
<template> <view class="content"> <head-nav></head-nav> <view class="content-main"></view> </view> </template>
效果圖:
微信小程序:
h5:
app:
在項(xiàng)目里面沒有針對(duì)h5時(shí)候需要導(dǎo)航欄做特別的限制,如果實(shí)際開發(fā)中在h5端不需要此導(dǎo)航欄,請(qǐng)?jiān)谀0嫔厦驷槍?duì)h5頁面加入條件編譯即可。
總結(jié)
到此這篇關(guān)于uniapp微信小程序自定義導(dǎo)航欄的文章就介紹到這了,更多相關(guān)uniapp自定義導(dǎo)航欄內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 微信小程序自定義頂部導(dǎo)航欄并適配不同機(jī)型實(shí)例詳解
- 微信小程序動(dòng)態(tài)設(shè)置導(dǎo)航欄標(biāo)題的實(shí)現(xiàn)步驟
- 小程序自定義tabbar導(dǎo)航欄及動(dòng)態(tài)控制tabbar功能實(shí)現(xiàn)方法(uniapp)
- 微信小程序使用uni-app實(shí)現(xiàn)首頁搜索框?qū)Ш綑诠δ茉斀?/a>
- uniapp小程序配置tabbar底部導(dǎo)航欄實(shí)戰(zhàn)指南
- 微信小程序自定義漸變的tabbar導(dǎo)航欄功能
- uniapp開發(fā)微信小程序自定義頂部導(dǎo)航欄功能實(shí)例
- 微信小程序?qū)崿F(xiàn)側(cè)邊導(dǎo)航欄
- 微信小程序?qū)崿F(xiàn)自定義導(dǎo)航欄
- 微信小程序自定義導(dǎo)航欄功能的實(shí)現(xiàn)
相關(guān)文章
JavaScript設(shè)置body高度為瀏覽器高度的方法
這篇文章主要介紹了JavaScript設(shè)置body高度為瀏覽器高度的方法,實(shí)例分析了body高度的設(shè)置技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-02-02自己編寫的支持Ajax驗(yàn)證的JS表單驗(yàn)證插件
創(chuàng)建一個(gè)JavaScript表單驗(yàn)證插件,可以說是一個(gè)繁瑣的過程,涉及到初期設(shè)計(jì)、開發(fā)與測(cè)試等等環(huán)節(jié)。實(shí)際上一個(gè)優(yōu)秀的程序員不僅是技術(shù)高手,也應(yīng)該是善假于外物的。本文介紹的這個(gè)不錯(cuò)的JavaScript表單驗(yàn)證插件,支持ajax驗(yàn)證,有需要的小伙伴可以參考下2015-05-05MATLAB中fillmissing函數(shù)用法小結(jié)
這篇文章主要介紹了MATLAB中fillmissing函數(shù)用法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-09-09js簡(jiǎn)單實(shí)現(xiàn)HTML標(biāo)簽Select聯(lián)動(dòng)帶跳轉(zhuǎn)
Select聯(lián)動(dòng)帶跳轉(zhuǎn)的效果想必大家并不陌生吧,下面有個(gè)不錯(cuò)的示例,感興趣的朋友可以參考下2013-10-10JS調(diào)用頁面表格導(dǎo)出excel示例代碼
這篇文章主要介紹了JS調(diào)用頁面表格導(dǎo)出excel的具體實(shí)現(xiàn),需要的朋友可以參考下2014-03-03Echarts讀取動(dòng)態(tài)數(shù)據(jù)完整代碼
這篇文章主要給大家介紹了關(guān)于Echarts讀取動(dòng)態(tài)數(shù)據(jù)的相關(guān)資料,使用Echarts畫圖時(shí),數(shù)據(jù)一般不是靜態(tài)寫死的,而是通過后端接口動(dòng)態(tài)獲取的,需要的朋友可以參考下2023-10-10