主要是在項目中,智酷君發現的一些問題json
其實,第一個問題,在最近的微信版本更新中已經優化了,經過 小程序模板消息 過來的,系統會自動加上home按鈕,但對於其餘的訪問方式則沒有支持~小程序
智酷君以前嘗試了各類解決方法,發現有一個問題,就是如今手機屏幕太多種多樣,有 傳統頭部、寬/窄劉海屏、水滴屏等等,沒法八門,不少解決方案都沒法解決特殊頭部,系統**「膠囊按鈕」** 和 自定義按鈕在Android屏幕可能有 幾像素不對齊 的問題(強迫症的噩夢)。bash
下面分享下一個相對比較完善的解決方案:微信
Link: developers.weixin.qq.com/s/cuUaCimT7…
ID: cuUaCimT72cHapp
智酷君作了一個demo代碼段,方便你們直接用IDE工具查看源碼~ xss
{
"usingComponents": {
"NavComponent": "/components/nav/common" //以插件的方式引入
},
"navigationStyle": "custom" //自定義頭部須要設置
}
複製代碼
若是須要自定義頭部,須要設置navigationStyle爲 「custom」async
<!-- home 類型的菜單 -->
<NavComponent v-title="自定義頭部" bind:commonNavAttr="commonNavAttr"></NavComponent>
<!-- 搜索菜單 -->
<NavComponent is-search="true" bind:commonNavAttr="commonNavAttr"></NavComponent>
複製代碼
能夠在自定義導航標籤上添加屬性配置來設置功能,具體按照實際須要來工具
│
├─components
│ └─nav
│ common.js
│ common.json
│ common.wxml
│ common.wxss
│
├─images
│ back.png
│ home.png
│
└─index
index.js
index.json
index.wxml
index.wxss
search.js
search.json
search.wxml
search.wxss
複製代碼
僅供參考post
const app = getApp();
Component({
properties: {
vTitle: {
type: String,
value: ""
},
isSearch:{
type: Boolean,
value: false
}
},
data: {
haveBack: true, // 是否有返回按鈕,true 有 false 沒有 若從分享頁進入則沒有返回按鈕
statusBarHeight: 0, // 狀態欄高度
navbarHeight: 0, // 頂部導航欄高度
navbarBtn: { // 膠囊位置信息
height: 0,
width: 0,
top: 0,
bottom: 0,
right: 0
},
cusnavH: 0, //title高度
},
// 微信7.0.0支持wx.getMenuButtonBoundingClientRect()得到膠囊按鈕高度
attached: function () {
if (!app.globalData.systeminfo) {
app.globalData.systeminfo = wx.getSystemInfoSync();
}
if (!app.globalData.headerBtnPosi) app.globalData.headerBtnPosi = wx.getMenuButtonBoundingClientRect();
console.log(app.globalData)
let statusBarHeight = app.globalData.systeminfo.statusBarHeight // 狀態欄高度
let headerPosi = app.globalData.headerBtnPosi // 膠囊位置信息
console.log(statusBarHeight)
console.log(headerPosi)
let btnPosi = { // 膠囊實際位置,座標信息不是左上角原點
height: headerPosi.height,
width: headerPosi.width,
top: headerPosi.top - statusBarHeight, // 膠囊top - 狀態欄高度
bottom: headerPosi.bottom - headerPosi.height - statusBarHeight, // 膠囊bottom - 膠囊height - 狀態欄height (膠囊實際bottom 爲距離導航欄底部的長度)
right: app.globalData.systeminfo.windowWidth - headerPosi.right // 這裏不能獲取 屏幕寬度,PC端打開小程序會有BUG,要獲取窗口高度 - 膠囊right
}
let haveBack;
if (getCurrentPages().length != 1) { // 當只有一個頁面時,而且是從分享頁進入
haveBack = false;
} else {
haveBack = true;
}
var cusnavH = btnPosi.height + btnPosi.top + btnPosi.bottom // 導航高度
console.log( app.globalData.systeminfo.windowWidth, headerPosi.width)
this.setData({
haveBack: haveBack, // 獲取是不是經過分享進入的小程序
statusBarHeight: statusBarHeight,
navbarHeight: headerPosi.bottom + btnPosi.bottom, // 膠囊bottom + 膠囊實際bottom
navbarBtn: btnPosi,
cusnavH: cusnavH
});
//將實際nav高度傳給父類頁面
this.triggerEvent('commonNavAttr',{
height: headerPosi.bottom + btnPosi.bottom
});
},
methods: {
_goBack: function () {
wx.navigateBack({
delta: 1
});
},
bindKeyInput:function(e){
console.log(e.detail.value);
}
}
})
複製代碼
解決不一樣屏幕頭部不對齊問題的終極辦法是 wx.getMenuButtonBoundingClientRect() 這個方法從微信7.0.0開始支持,經過這個方法咱們能夠獲取到右邊系統膠囊的top、height、right等屬性,這樣不管是水滴屏、劉海屏、異形屏,都能完美對齊右邊系統默認的膠囊bar,完美治癒強迫症~性能
//app.js
App({
/**
* 加載頁面
* @param {*} options
*/
onShow: function (options) {
},
onLaunch: async function () {
let self = this;
//設置默認分享
this.globalData.shareData = {
title: "智酷方程式"
}
// this.getSysInfo();
},
globalData: {
//默認分享文案
shareData: {},
qrCodeScene: false, //二維碼掃碼進入傳參
systeminfo: false, //系統信息
headerBtnPosi: false, //頭部菜單高度
}
});
複製代碼
將獲取的參數存儲在一個全局變量globalData中,能夠減小反覆調用的性能消耗。
<view class="custom_nav" style="height:{{navbarHeight}}px;">
<view class="custom_nav_box" style="height:{{navbarHeight}}px;">
<view class="custom_nav_bar" style="top:{{statusBarHeight}}px; height:{{cusnavH}}px;">
<!-- 搜索部分-->
<block wx:if="{{isSearch}}">
<input class="navSearch"
style="height:{{navbarBtn.height-2}}px;line-height:{{navbarBtn.height-4}}px; top:{{navbarBtn.top+1}}px; left:{{navbarBtn.right}}px; border-radius:{{navbarBtn.height/2}}px;"
maxlength="10" bindinput="bindKeyInput" placeholder="輸入文字搜索" />
</block>
<!-- HOME 部分-->
<block wx:else>
<view class="custom_nav_icon {{!haveBack||'borderLine'}}"
style="height:{{navbarBtn.height}}px;line-height:{{navbarBtn.height-2}}px; top:{{navbarBtn.top}}px; left:{{navbarBtn.right}}px; border-radius:{{navbarBtn.height/2}}px;">
<view wx:if="{{haveBack}}" class="icon-back" bindtap='_goBack'>
<image src='/images/back.png' mode='aspectFill' class='back-pre'></image>
</view>
<view wx:if="{{haveBack}}" class='navbar-v-line'></view>
<view class="icon-home">
<navigator class="home_a" url="/pages/home/index" open-type="switchTab">
<image src='/images/home.png' mode='aspectFill' class='back-home'></image>
</navigator>
</view>
</view>
<view class="nav_title" style="height:{{cusnavH}}px; line-height:{{cusnavH}}px;">
{{vTitle}}
</view>
</block>
</view>
</view>
</view>
複製代碼
主要是對幾種狀態的判斷和定位的計算。
/* components/nav/test.wxss */
.custom_nav {
width: 100%;
background: #3a7dd7;
position: relative;
z-index: 99999;
}
.custom_nav_box {
position: fixed;
width: 100%;
background: #3a7dd7;
z-index: 99999;
border-bottom: 1rpx solid rgba(255, 255, 255, 0.3);
}
.custom_nav_bar {
position: relative;
z-index: 9;
}
.custom_nav_box .nav_title {
font-size: 28rpx;
color: #fff;
text-align: center;
position: absolute;
max-width: 360rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
z-index: 1;
}
.custom_nav_box .custom_nav_icon {
position:absolute;
z-index: 2;
display: inline-block;
border-radius: 50%;
vertical-align: top;
font-size:0;
box-sizing: border-box;
}
.custom_nav_box .custom_nav_icon.borderLine {
border: 1rpx solid rgba(255, 255, 255, 0.3);
background: rgba(0, 0, 0, 0.1);
}
.navbar-v-line {
width: 1px;
margin-top: 14rpx;
height: 32rpx;
background-color: rgba(255, 255, 255, 0.3);
display: inline-block;
vertical-align: top;
}
.icon-back {
display: inline-block;
width: 74rpx;
padding-left: 20rpx;
vertical-align: top;
/* margin-top: 12rpx;
vertical-align: top; */
height: 100%;
}
.icon-home {
/* margin-top: 8rpx;
vertical-align: top; */
display: inline-block;
width: 80rpx;
text-align: center;
vertical-align: top;
height: 100%;
}
.icon-home .home_a {
height: 100%;
display: inline-block;
vertical-align: top;
width: 35rpx;
}
.custom_nav_box .back-pre,
.custom_nav_box .back-home {
width: 35rpx;
height: 35rpx;
vertical-align: middle;
}
.navSearch {
width: 200px;
background: #fff;
font-size: 14px;
position: absolute;
padding: 0 20rpx;
z-index: 9;
}
複製代碼
往期回顧: