相信不少小伙伴在开发微信小程序的时候都会有自定义顶部导航栏的需求,不够要说明的是小程序右上角的胶囊是不能自定义的哦,除了胶囊其余地方都是能够根据本身的项目而定了,在一次小程序开发中就须要对顶部进行自定义在此记录一下本身封装这个组件的过程。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() {}
});
复制代码
效果以下: