相信不少小夥伴在開發微信小程序的時候都會有自定義頂部導航欄的需求,不夠要說明的是小程序右上角的膠囊是不能自定義的哦,除了膠囊其餘地方都是能夠根據本身的項目而定了,在一次小程序開發中就須要對頂部進行自定義在此記錄一下本身封裝這個組件的過程。json
既然今天須要把導航欄封裝爲組件那麼就須要如下幾個步驟:小程序
首先搭建一個以下圖的結構:微信小程序
此時咱們就須要根據官方文檔查看得知若是要定製必須在配置文件中修改默認的配置文件,其實這裏能夠針對某個頁面page進行設置,以index爲例在index.json文件中配置以下代碼便可看到以下效果:api
<view class='topbar'>
<view class='status' style="height:{{statusHeight}}px"></view>
<view class='navbar' style="height:{{navHeight}}px">
<view class='navbar_back' bindtap='backClick'>
<image src='../images/black_back.png'></image>
</view>
<view class='navbar_title' style="height:{{navHeight}}px">
<view>標題</view>
</view>
</view>
</view>
複製代碼
這裏的主要思路就是用fixed定位,後面會有內容頂到底部的佈局,因此所有用定位會方便些,總體就兩個部分一個是狀態欄一個就是標題和按鈕的部分了。bash
.topbar {
position: fixed;
left: 0;
top: 0;
width: 100%;
z-index: 9999;
}
.status {
width: 100%;
}
.navbar {
width: 100%;
display: flex;
justify-content: flex-start;
align-items: center;
position: relative;
}
.navbar_back {
padding: 0 32rpx;
display: flex;
justify-content: flex-start;
align-items: center;
height: 100%;
}
.navbar_back image {
width: 21rpx;
height: 34rpx;
}
.navbar_title {
position: absolute;
left: 0;
top: 0;
width: 100%;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
z-index: -1;
}
.navbar_title view {
width: 40%;
word-break: break-all;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 38rpx;
}
複製代碼
樣式中沒有太多的東西,惟一須要說的就是大部分模塊都是定位作的,惟一沒考慮好的就是標題太長很差處理,這裏用了簡單粗暴的方法給設定一個寬度。微信
Component({
properties: {
/**
* 自定義返回事件處理
* customBackReturn="{{true}}" bind:customBackReturn="customBackReturn"
*/
customBackReturn: {
type: Boolean,
value: false
}
},
data: {
},
methods: {
backClick() {
if (this.data.customBackReturn) {
this.triggerEvent("customBackReturn")
} else {
if (getCurrentPages().length == 1) {
wx.switchTab({
url: '/pages/index/index',
})
} else {
wx.navigateBack({
delta: 1
})
}
}
}
},
attached() {
var self = this;
wx.getSystemInfo({
success(res) {
var isIos = res.system.indexOf('iOS') > -1;
self.setData({
statusHeight: res.statusBarHeight,
navHeight: isIos ? 44 : 48
})
}
})
}
})
複製代碼
邏輯中主要在兩個地方一個是獲取系統信息時對於導航高度的判斷,另一個是返回上一頁的邏輯,默認就是打開首頁(注意用的api),若是有自定義事件就用自定義事件customBackReturnapp
目前效果就和沒有自定義以前差很少就是一個普通的返回按鈕和標題文字,以下圖:佈局
小程序中特別是分享出去的頁面,若是沒有一個返回主頁的按鈕,用戶更本不知道怎麼回到小程序的主頁,因此給用戶帶來了很大的不便,所以這樣的需求就必需要有了,若是實現呢?其實很簡單,畢竟已經出來一個了,須要的就是加一個上去就好了。測試
<view class='topbar'>
<view class='status' style="height:{{statusHeight}}px"></view>
<view class='navbar' style="height:{{navHeight}}px">
<view class='navbar_home'>
<image src='../images/black_back.png' bindtap='backClick'></image>
<image src='../images/home_black.png' bindtap='homeClick'></image>
</view>
<!-- <view class='navbar_back' bindtap='backClick'>
<image src='../images/black_back.png'></image>
</view> -->
<view class='navbar_title' style="height:{{navHeight}}px">
<view>標題</view>
</view>
</view>
</view>
複製代碼
你們注意到我把以前的代碼註釋了而不是直接在前面的代碼上修改,其實這裏留着是爲了後面能夠自定義想要那種導航形式。flex
.navbar_home {
margin-left: 32rpx;
display: flex;
justify-content: flex-start;
align-items: center;
border-radius: 33rpx;
border: 1px solid rgba(0, 0, 0, 0.1);
background: rgba(0,0,0,0.2);
box-sizing: border-box;
padding: 10rpx 0;
}
.navbar_home image:first-child {
width: 21rpx;
height: 34rpx;
padding: 0 32rpx;
border-right: 1px solid rgba(255,255,255,0.2);
}
.navbar_home image:last-child {
width: 37rpx;
height: 35rpx;
padding: 0 32rpx;
}
複製代碼
一樣的樣式也只是在以前的基礎上增長了上面這些樣式。
homeClick() {
wx.switchTab({
url: '/pages/index/index',
})
}
複製代碼
邏輯也只是在methods中添加一個返回主頁的事件而已,這裏須要你們根據本身的項目狀況而定。
樣式你們能夠根據本身項目而定。
到這兩部分的功能都完成了,可是若是如今咱們在首頁中添加一些內容你就會發現問題了,以下:
<view style="height:{{statusHeight+navHeight}}px" hidden='{{false}}'></view>
<view class='topbar'>
<view class='status' style="height:{{statusHeight}}px"></view>
<view class='navbar' style="height:{{navHeight}}px">
<view class='navbar_home'>
<image src='../images/black_back.png' bindtap='backClick'></image>
<image src='../images/home_black.png' bindtap='homeClick'></image>
</view>
<!-- <view class='navbar_back' bindtap='backClick'>
<image src='../images/black_back.png'></image>
</view> -->
<view class='navbar_title' style="height:{{navHeight}}px">
<view>標題</view>
</view>
</view>
</view>
複製代碼
效果以下:
爲了能使使用更加方便,須要對上面的導航欄進行進一步封裝以適應不一樣需求。
首先須要改造的就是結構,讓更多的選項可以進行配置,結構改造以下:
<view style="height:{{statusHeight+navHeight}}px" hidden='{{header.hiddenBlock}}'></view>
<view class='topbar' style="background:{{header.headerbg}}">
<view class='status' style="height:{{statusHeight}}px"></view>
<view class='navbar' style="height:{{navHeight}}px">
<block wx:if="{{header.slot}}">
<slot></slot>
</block>
<block wx:else>
<view class='navbar_home' wx:if="{{header.homeCapsule}}" style="background:{{header.capsulebg}};border:{{header.capsuleborder}}">
<image src='../images/black_back.png' bindtap='backClick' style="border-right:{{header.capsulesep}}"></image>
<image src='../images/home_black.png' bindtap='homeClick'></image>
</view>
<view class='navbar_back' bindtap='backClick' wx:else>
<image src='../images/black_back.png'></image>
</view>
<view class='navbar_title' style="height:{{navHeight}}px">
<view style="color:{{header.fontColor}};font-size:{{header.fontSize}}">{{header.title}}</view>
</view>
</block>
</view>
</view>
複製代碼
上面全部的參數都是能夠配置的,這就大大的給了開發者定製不一樣風格了,若是仍是有不符合的建議你直接修改上面的代碼或者本身封裝一個更好。
Component({
properties: {
header: {
type: Object,
value: {
homeCapsule: false,
headerbg: "#fff",
title: "",
fontColor: "#000",
fontSize: '16',
hiddenBlock: false,
capsulebg: 'rgba(0,0,0,0.2)',
capsuleborder: '1px solid rgba(0, 0, 0, 0.1)',
capsulesep: '1px solid rgba(255,255,255,0.2)',
slot: false
}
},
/**
* 自定義返回事件處理
* customBackReturn="{{true}}" bind:customBackReturn="customBackReturn"
*/
customBackReturn: {
type: Boolean,
value: false
}
},
methods: {
backClick() {
if (this.data.customBackReturn) {
this.triggerEvent("customBackReturn")
} else {
if (getCurrentPages().length == 1) {
wx.switchTab({
url: '/pages/index/index',
})
} else {
wx.navigateBack({
delta: 1
})
}
}
},
homeClick() {
wx.switchTab({
url: '/pages/index/index',
})
}
},
attached() {
var self = this;
wx.getSystemInfo({
success(res) {
var isIos = res.system.indexOf('iOS') > -1;
self.setData({
statusHeight: res.statusBarHeight,
navHeight: isIos ? 44 : 48
})
}
})
}
})
複製代碼
結構的改造其實就是添加一些可以傳入的值來定製化。
到這裏基本上這個組件就封裝好了,接下來就是使用這個組件了。
這種方式的應用很簡單直接配置一些參數便可。
{
"navigationStyle":"custom",
"usingComponents": {
"header":"../../components/navbar/navbar"
}
}
複製代碼
須要配置導航欄自定義,否則就沒有效果,根據本身的路徑引入便可,若是全部頁面都須要用到,建議直接在app.json中配置,這樣就不用每一個頁面去配置了。
<header header='{{header}}'></header>
<view>內容區域哦</view>
複製代碼
在須要用到的頁面使用header標籤便可
Page({
data: {
header:{
homeCapsule: false,
title: '標題',
fontColor: "#000",
fontSize: '36rpx',
headerbg: '#f40',
hiddenBlock: false,
slot: false
}
},
onLoad: function() {}
});
複製代碼
這裏有三個參數是必需要配置的:homeCapsule,hiddenBlock,slot三個參數分別表明的含義是是否顯示帶有home按鈕的,是否隱藏整個頂部(後面會介紹),是否須要自定義結構
有時候須要將內容置頂,看起來會比較好看,因此就須要對hiddenBlock進行配置了,看代碼:
<header header='{{header}}'></header>
<image src='../../images/timg.jpg' style="width:100%" mode="aspectFill"></image>
<view>內容區域哦</view>
複製代碼
重要的是如何配置,以下:
Page({
data: {
header:{
homeCapsule: false,
title: '',
headerbg: 'transparent',
hiddenBlock: true,
slot: false
}
},
onLoad: function() {}
});
複製代碼
效果以下:
分享頁須要帶有返回首頁的按鈕,如何配置呢?有了這個組件就很容易配置了,配置以下:
Page({
data: {
header:{
homeCapsule: true,
title: '測試標題',
headerbg: '#f40',
hiddenBlock: false,
slot: false
}
},
onLoad: function() {}
});
複製代碼
效果以下:
若是以上都不能知足需求,那麼只有本身寫了,簡單實例以下:
<header header='{{header}}'>
<view>測試的標題哦</view>
</header>
<image src='../../images/timg.jpg' style="width:100%" mode="aspectFill"></image>
<view>內容區域哦</view>
複製代碼
配置以下:
Page({
data: {
header:{
headerbg: 'transparent',
hiddenBlock: false,
slot: true
}
},
onLoad: function() {}
});
複製代碼
效果以下: