业务需求,官网自带的navBar并不符合当前业务,所以需要使用自定义navBar来实现UI设计稿的样式需求。
首先我们来看看效果
类型2 类型1 类型3当前业务只用到了这三种类型,下面我们就分析一下如何实现。
第一步
要使用自定义navBar需要在根目录的app.json当中找到“window”配置项,添加"navigationStyle": "custom"
开启自定义navBar第二步
接下来我们就可以开心的使用自定义navbar了。
但是,先别开心的太早,上一步设置了"navigationStyle": "custom"之后,刷新页面发现,默认的navbar头部导航没有了,头部现在什么都没有。
那这就需要我们自己去编写navbar组件了。
第三步
在根目录新建一个components文件夹,新建好之后把鼠标焦点放在components位置右键再新建一个文件夹,我们命名为navbar,最后在navbar文件夹下新建一个component,命名为index。
新建component最后的目录结构就是这样的啦~~
结构
第四步
组件我们已经新建好了,接下来就开始编写组件啦~
第一个我们会遇到的问题就是,如何判断这个navbar导航栏的高度。小程序的导航栏高度由两块组件,一个是状态栏的高度,一个导航栏高度。
状态栏高度可以通过小程序的APi获取,而导航栏高度则需要自己去计算。这个计算需要兼容尽可能多的设备。确保不同设备都符合对应的尺寸。
在app.js中我们通过wx.getSystemInfo()方法来获取导航栏高度,和状态栏高度。并且把两个高度放在全局变量里面。方便自定义组件中调用。
// 获取设备信息
wx.getSystemInfo({
success: res => {
this.globalData.statusBarHeight = res.statusBarHeight; // 状态栏高度
this.globalData.navbarHeight = res.system.toLowerCase().indexOf('ios') > -1 ? 44 : 48; // 导航栏高度
}
})
高度
第五步
获取到了两个的高度之后就可以开始写组件了。
在navbar/index.js页面的顶部添加const app = getApp();
通过getApp()来获取全局数据。
在data中赋值
/**
* 组件的初始数据
*/
data: {
statusBarHeight: app.globalData.statusBarHeight,
navbarHeight: app.globalData.navbarHeight,
},
然后在wxml中设置组件的高度为navbarHeight+ statusBarHeight。我的业务是让statusBarHeight透明,随系统变化,所以用的padding-top来设置,可以按照自己的业务需求来设置。
打开index.wxml页面,写页面布局和样式。
<!--components/navbar/index.wxml-->
<view class="navbar" style="padding-top:{{statusBarHeight}}px;height:{{navbarHeight}}px;line-height:{{navbarHeight}}px;background:{{background}};">
<!-- <view></view> -->
<!-- 首页标题 -->
<view wx:if="{{typeBar===1}}" class="bavbar-flex">
<!-- <view class="nav-left"></view> -->
<view class="nav-title home-title">{{name}}</view>
<view class="nav-right"></view>
</view>
<!-- 采购、值得买 -->
<view wx:if="{{typeBar===3}}" class="bavbar-flex">
<view class="nav-left">
<view class="nav-left-box">
<view class="go-back" bindtap="goHome">
<text class="iconfont icon-shouye-"></text>
</view>
</view>
</view>
<view class="nav-title" style="width: calc(100vw - 97px);">{{name}}</view>
<view class="nav-right"></view>
</view>
<!-- 返回上一页按钮和标题 -->
<view wx:if="{{typeBar===2}}" class="bavbar-flex">
<view class="nav-left">
<view class="nav-left-box">
<view class="go-back" bindtap="goBack">
<text class="iconfont icon-back"></text>
</view>
<view class="line"></view>
<view class="go-back" bindtap="goHome">
<text class="iconfont icon-shouye-"></text>
</view>
</view>
</view>
<view class="nav-title" style="width: calc(100vw - 194px);">{{name}}</view>
<view class="nav-right"></view>
</view>
</view>
上面写了三种类型,每一个类型都有点击事件,我们把点击事件都写进index.js页面中,同时,还设置了几个变量,分别是name(导航标题名称)、typeBar(类型)、share(是否为分享状态)、background(背景色),这些变量由组件使用的时候动态添加,我们可以给它们先设置默认值。最后index.js完整代码如下
// components/navbar/index.js
const app = getApp();
Component({
/**
* 组件的属性列表
*/
properties: {
// 这里定义了innerText属性,属性值可以在组件使用时指定
name: {
type: String,
value: '养博城',
},
typeBar: {
type: Number,
value: 1,
},
share: {
type: Number,
value: 2
},
background: {
type: String,
value: '#fff'
}
},
/**
* 组件的初始数据
*/
data: {
statusBarHeight: app.globalData.statusBarHeight,
navbarHeight: app.globalData.navbarHeight,
},
/**
* 组件的方法列表
*/
methods: {
// 返回上一页
goBack() {
if (this.data.share == 1) {
wx.switchTab({
url: '/pages/tabBar/index/index',
})
} else {
wx.navigateBack()
}
},
// 返回首页
goHome() {
wx.switchTab({
url: '/pages/tabBar/index/index',
})
},
// 返回首页
goBackHome() {
wx.switchTab({
url: '/pages/tabBar/index/index',
})
},
}
})
因为我的页面使用了第三方的图标,需要自己额外去引入,参考阿里图标
/* components/navbar/index.wxss */
/* 图标 */
@import "/assets/iconfont/iconfont";
/* 导航头 */
.navbar {
display: flex;
align-items: center;
color: #141414;
}
/* 导航标题 */
.nav-title {
flex: 1;
font-size: 18px;
font-family: PingFang SC;
font-weight: bold;
color: rgba(20, 20, 20, 1);
opacity: 1;
text-align: center;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.home-title {
text-align: left;
padding-left: 40rpx;
}
/* 共有样式 */
.nav-left, .nav-right {
/* width: 97px; */
height: 30px;
}
/* 左边 */
.nav-left {
padding-left: 12px;
}
.nav-left-box {
background: rgba(255, 255, 255, 0.5);
border: 1px solid rgba(0, 0, 0, 0.1);
height: 30px;
line-height: 30px;
border-radius: 28px;
display: flex;
align-items: center;
color: #000;
width: auto;
}
.line {
height: 19px;
background: rgba(208, 208, 208, 1);
opacity: 1;
width: 1px;
}
/* 返回按钮 */
.go-back {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
padding: 0 24rpx;
}
/* 返回按钮的字体大小 */
.icon-back {
font-size: 18px;
}
/* 回首页按钮 */
.icon-shouye {
font-size: 18px;
}
/* 右边 */
/* .nav-right {
} */
/* 导航内容 类型 */
.bavbar-flex {
width: 100vw;
flex: 1;
margin-right: 6rem;
display: flex;
align-items: center;
}
网友评论