提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
一、自定义tabBar的实现
1.全局配置
2.主页面
3.CustomTabBar组件
4.效果
前言
小程序自带的tabBar可以参考这篇文章:https://cloud.tencent.com/developer/article/1945495
因为小程序自带的tabBar,比较单一,无法满足多样化需求,这样就需要自己自定义tabBar。
一、自定义tabBar的实现
1.全局配置
全局app.json配置文件禁用自带tabBa
代码语言:javascript复制"tabBar": {
"custom": false,
"list": [
{
"pagePath": "pages/index",
"iconPath": "components/custom-tab-bar/component.png",
"selectedIconPath": "components/custom-tab-bar/component-on.png",
"text": "首页"
},
{
"pagePath": "pages/index2",
"iconPath": "components/custom-tab-bar/component.png",
"selectedIconPath": "components/custom-tab-bar/component-on.png",
"text": "首页2"
},
{
"pagePath": "pages/index3",
"iconPath": "components/custom-tab-bar/component.png",
"selectedIconPath": "components/custom-tab-bar/component-on.png",
"text": "自定义"
}
]
}
2.主页面
代码语言:javascript复制<!--miniprogram/pages/3.10/custom/index.wxml-->
<text>我是自定义组件l</text>
<CustomTabBar index="0" bindpagenavigating="onPageNavigating"></CustomTabBar>
代码语言:javascript复制// miniprogram/pages/3.12/index.js
Page({
/**
* 页面的初始数据
*/
data: {
initData:{}
},
async onPageNavigating(e){
let res = await wx.wxp.request({
url: 'http://localhost:3000/hi?name=index2',
})
e.detail.eventCallback({
openType:"initData",
openData:{
a:res.data
}
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
const eventChannel = this.getOpenerEventChannel()
if (eventChannel.on){
eventChannel.on('initData', (data)=> {
console.log("data",data)
this.setData({
initData:data
})
})
}
},
})
3.CustomTabBar组件
iconfont.wxss
代码语言:javascript复制@keyframes icon-spin {
0% {
-webkit-transform: rotate(0);
transform: rotate(0);
}
100% {
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
.iconfont-spin {
-webkit-animation: icon-spin 2s infinite linear;
animation: icon-spin 2s infinite linear;
display: inline-block;
}
.iconfont-pulse {
-webkit-animation: icon-spin 1s infinite steps(8);
animation: icon-spin 1s infinite steps(8);
display: inline-block;
}
.cu-icon-font{
font-family:"iconfont" !important;
font-size:inherit;
font-style:normal;
}
index.js
代码语言:javascript复制Component({
behaviors: [require('../../lib/event-behavior.js')],
properties: {
index: {
type: Number,
value: 0
}
},
data: {
selected: 0,
list: [{
pagePath: "/pages/3.12/index",
iconPath: "/components/custom-tab-bar/component.png",
selectedIconPath: "/components/custom-tab-bar/component-on.png",
text: "index",
iconClass:"icon-homefill",
iconTopClass:""
}, {
pagePath: "/pages/3.12/index2/index",
iconPath: "/components/custom-tab-bar/component.png",
selectedIconPath: "/components/custom-tab-bar/component-on.png",
text: "index",
iconClass:"cu-btn icon-add bg-green shadow",
iconTopClass:"add-action"
},{
pagePath: "/pages/3.12/index3/index",
iconPath: "/components/custom-tab-bar/component.png",
selectedIconPath: "/components/custom-tab-bar/component-on.png",
text: "自定义",
iconClass:"icon-my",
iconTopClass:""
}]
},
observers: {
"index": function (id) {
this.setData({ selected: id});
}
},
methods: {
async goToTab(e){
let targetPageUrl = e.currentTarget.dataset.url
// 派发一个事件,让外部业务代码处理,待处理完了,再回到这里
let pageData = await this.triggerWaitingEvent("pagenavigating", {
targetPageUrl
})
let res = await wx.wxp.navigateTo({
url:targetPageUrl
})
if (res.eventChannel){
res.eventChannel.emit(pageData.openType, pageData.openData)
}
}
}
})
event-behavior.js
代码语言:javascript复制// 派发一个等待处理,需要有代码处理的事件
module.exports = Behavior({
definitionFilter(defFields) {
defFields.methods.triggerWaitingEvent = function (type, data = {}){
return new Promise((resolve,reject)=>{
let eventCallback = res => resolve(res)
Object.assign(data, {
eventCallback
})
this.triggerEvent(type, data)
})
}
},
})
index.wxml
代码语言:javascript复制<view class="tabBar">
<view class="tabbg"></view>
<view class="cu-bar tabbar">
<view wx:for="{{list}}" wx:for-item="item" wx:key="index" class="action {{item.iconTopClass}} {{selected == index?'text-green':''}}" catchtap='goToTab' data-url="{{item.pagePath}}" data-path="{{item.pagePath}}" data-index="{{index}}">
<view class='iconf {{item.iconClass}}'></view>
<view>{{item.text}}</view>
</view>
</view>
</view>
index.wxss
代码语言:javascript复制@import './iconfont.wxss';
.tabbg{
background: rgba(255,255,255,1);
width: 100%;
height: 100rpx;
position: absolute;
bottom: 0;
box-shadow: 0 1rpx 6rpx rgba(0, 0, 0, 0.1);
}
.iconf {
font-family: "iconfont" !important;
font-size: inherit;
font-style: normal;
}
.tabBar{
width:100%;
position: fixed;
bottom:0;
font-size:20rpx;
color:#8A8A8A;
}
.text-green{
color: #39b54a;
}
.shadow {
box-shadow: 0 1rpx 6rpx rgba(0, 0, 0, 0.1);
}
.bg-red {
background-color: #e54d42;
color: #fff;
}
.bg-orange {
background-color: #f37b1d;
color: #fff;
}
.bg-yellow {
background-color: #fbbd08;
color: #333;
}
.bg-olive {
background-color: #8dc63f;
color: #fff;
}
.bg-green {
background-color: #39b54a;
color: #fff;
}
.bg-cyan {
background-color: #1cbbb4;
color: #fff;
}
.bg-blue {
background-color: #0081ff;
color: #fff;
}
.bg-purple {
background-color: #6739b6;
color: #fff;
}
.bg-mauve {
background-color: #9c26b0;
color: #fff;
}
.bg-pink {
background-color: #e03997;
color: #fff;
}
.bg-brown {
background-color: #a5673f;
color: #fff;
}
.bg-grey {
background-color: #8799a3;
color: #fff;
}
.bg-gray {
background-color: #f0f0f0;
color: #666;
}
.bg-black {
background-color: #333;
color: #fff;
}
.bg-white {
background-color: #fff;
color: #666;
}
.shadow .bg-green {
box-shadow: 6rpx 6rpx 8rpx rgba(48, 156, 63, 0.2);
}
.cu-bar.tabbar .action.add-action .icon-add {
position: absolute;
width: 70rpx;
z-index: 2;
height: 70rpx;
border-radius: 50%;
line-height: 70rpx;
font-size: 50rpx;
top: -35rpx;
left: 0;
right: 0;
margin: auto;
padding: 0;
}
.cu-bar.tabbar .action.add-action::after {
content: "";
position: absolute;
width: 100rpx;
height: 100rpx;
top: -50rpx;
left: 0;
right: 0;
margin: auto;
box-shadow: 0 -3rpx 8rpx rgba(0, 0, 0, 0.08);
border-radius: 50rpx;
background-color: rgba(255, 255, 255, 1);
z-index: 0;
}
.cu-bar.tabbar .action.add-action::before {
content: "";
position: absolute;
width: 100rpx;
height: 30rpx;
bottom: 30rpx;
left: 0;
right: 0;
margin: auto;
background-color: inherit;
z-index: 1;
}
.cu-btn {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
box-sizing: border-box;
padding: 0 30rpx;
font-size: 28rpx;
height: 64rpx;
line-height: 1;
text-align: center;
text-decoration: none;
overflow: visible;
margin-left: initial;
transform: translate(0rpx, 0rpx);
margin-right: initial;
}
.cu-btn::after {
display: none;
}
.cu-bar {
display: flex;
position: relative;
align-items: center;
min-height: 100rpx;
justify-content: space-between;
background: rgba(0,0,0,0);
}
.cu-bar .action {
display: flex;
align-items: center;
height: 100%;
justify-content: center;
max-width: 100%;
}
.cu-bar.tabbar .action .icon-add {
width: 100rpx;
position: relative;
display: block;
height: auto;
margin: 0 auto 10rpx;
text-align: center;
font-size: 40rpx;
}
/* safe-area-inset-*由四个定义了视口边缘内矩形的 top, right, bottom 和 left 的环境变量组成,这样可以安全地放入内容。 */
.cu-bar.tabbar {
padding: 0;
z-index: 0;
height: calc(130rpx env(safe-area-inset-bottom) / 2);
padding-bottom: calc(env(safe-area-inset-bottom) / 2);
}
.cu-bar {
margin-top: 20rpx;
}
.cu-bar .action:first-child {
margin-left: 30rpx;
font-size: 30rpx;
}
.cu-bar.tabbar .action {
font-size: 22rpx;
position: relative;
flex: 1;
text-align: center;
padding: 0;
display: block;
height: auto;
line-height: 1;
margin: 0;
background-color: inherit;
overflow: initial;
padding-top: 30rpx;
}
.cu-bar.tabbar .action.add-action {
position: relative;
z-index: 2;
padding-top: 0;
}
.icon-homefill {
width: 100rpx;
position: relative;
display: block;
height: auto;
margin: 0 auto 10rpx;
text-align: center;
font-size: 40rpx;
}
.icon-add {
width: 100rpx;
position: relative;
display: block;
height: auto;
margin: 0 auto 10rpx;
text-align: center;
font-size: 40rpx;
}
.icon-my {
width: 100rpx;
position: relative;
display: block;
height: auto;
margin: 0 auto 10rpx;
text-align: center;
font-size: 40rpx;
}
.icon-homefill:before { content: "e6bb"; }
.icon-my:before { content: "e78b"; }
.icon-add:before { content: "e6da";
4.效果