支付宝小程序内的自定义tabbar功能需求提了有两年了,在近期官方同学同步该功能已实现,下午花了点时间实现了该功能,将实操经验分享出来给大家,避免踩坑。
给大家看下效果图:
tabBar 作为支付宝小程序基础能力,提供底部操作栏进行切换页面。自定义 tabBar 作为补充能力,可以让开发者更加灵活地设置 tabBar,以满足更多个性化的场景。
在自定义 tabBar 模式下:
●开发者需要提供一个自定义组件来进行 tabBar 的渲染及交互。
●与 tabBar 样式相关的接口将失效。如 my.hideTabBar 等。
●每个页面的 tabBar 组件实例是不同的,可通过 getTabBar 接口获取 tabBar 组件实例。
版本要求:
●基础库 2.7.20 或更高版本。
●支付宝客户端 10.2.63 或更高版本。
●小程序开发者工具 3.1.2 或更高版本。
IDE下载地址:
https://opendocs.alipay.com/mini/ide/download
下载安装3.1.2beta版本IDE后,左上角设置里默认基础库是 2.7.21
接下来是实操阶段:
第一步:app.json中指定当前tabbar为自定义tabbar
{ "pages": [ "pages/index/index", "pages/alipayMent/index", "pages/poster/index", "pages/canvas/index", "pages/imgCopper/index", ], "tabBar": { "textColor": "#6C6C6C", "selectedColor": "#1ECDB9", "backgroundColor": "#ffffff", "customize": true, // 这里设置该属性为true,即指定当前tabbar为自定义tabbar "items": [ { "pagePath": "pages/index/index", "name": "候选人", "icon": "/assets/img/xcx_b_apply_normal.png", "activeIcon": "/assets/img/xcx_b_apply_active.png" }, { "pagePath": "pages/imgCopper/index", "name": "职位", "icon": "/assets/img/xcx_b_job_normal.png", "activeIcon": "/assets/img/xcx_b_job_active.png" }, { "pagePath": "pages/poster/index", "name": "", "icon": "https://qiniu-image.qtshe.com/miniapp_publish_job.png", "activeIcon": "https://qiniu-image.qtshe.com/miniapp_publish_job.png" }, { "pagePath": "pages/canvas/index", "name": "消息", "icon": "/assets/img/xcx_b_job_normal.png", "activeIcon": "/assets/img/xcx_b_job_active.png" }, { "pagePath": "pages/alipayMent/index", "name": "我的", "icon": "/assets/img/xcx_b_mine_normal.png", "activeIcon": "/assets/img/xcx_b__mine_active.png" } ] }, "window": { "defaultTitle": "支付宝serverless拓荒" } }
第二步:在pages同级新建一个customize-tab-bar组件,该组件就相当于一个自定义组件,内部代码如下:
// axml相关 <view class="tabbar_box"> <view class="tabbar_nav {{index === 2 ? 'active' : ''}}" onTap="switchTab" data-index="{{index}}" data-item={{item}} a:for="{{tabBar.items}}" a:key="index"> <!-- 图标 --> <image class="tabbar_icon" src="{{selected === index ? item.activeIcon : item.icon}}"></image> <!-- 文字 --> <text style="color:{{selected === index ? tabBar.selectedColor : tabBar.textColor}}" >{{item.name}}</text> </view> </view>
// acss样式 .tabbar_box { display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; -ms-flex-direction: row; flex-direction: row; -ms-flex-pack: distribute; justify-content: space-around; position: fixed; bottom: 0; left: 0; z-index: 999; width: 100%; box-shadow: 0 1rpx 6rpx rgba(0, 0, 0, 0.2); background: #ffffff; padding-top: 16rpx; padding-bottom: env(safe-area-inset-bottom); box-sizing: content-box; } .tabbar_nav { display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; -webkit-box-pack: center; -ms-flex-pack: center; justify-content: space-around; -webkit-box-align: center; -ms-flex-align: center; align-items: center; font-size: 25rpx; height: 100%; flex: 1; background: #fff; } .tabbar_nav.active { padding-top: 50rpx; } .tabbar_nav.active image { width: 100rpx; z-index: 2; height: 100rpx; border-radius: 50%; line-height: 100rpx; font-size: 50rpx; top: -50rpx; left: 0; right: 0; margin: auto; padding: 0; position: absolute; } .tabbar_nav.active::after { content: ""; position: absolute; width: 120rpx; height: 120rpx; top: -60rpx; left: 0; right: 0; margin: auto; box-shadow: 0 -3rpx 8rpx rgba(0, 0, 0, 0.06); border-radius: 60rpx; background-color: inherit; z-index: 0; } .tabbar_nav.active::before { content: ""; position: absolute; width: 120rpx; height: 30rpx; bottom: 30rpx; left: 0; right: 0; margin: auto; background-color: inherit; z-index: 1; } .tabbar_icon { width: 40rpx; height: 40rpx; } .tabbar_nav text { font-size: 24rpx; margin-top: 6rpx; }
// JS相关 Component({ data: { selected: 0, tabBar: { textColor: "#6C6C6C", selectedColor: "#1ECDB9", items: [ { pagePath: "/pages/index/index", name: "候选人", icon: "/assets/img/xcx_b_apply_normal.png", activeIcon: "/assets/img/xcx_b_apply_active.png" }, { pagePath: "/pages/imgCopper/index", name: "职位", icon: "/assets/img/xcx_b_job_normal.png", activeIcon: "/assets/img/xcx_b_job_active.png" }, { pagePath: "/", name: "", icon: "https://qiniu-image.qtshe.com/miniapp_publish_job.png", activeIcon: "https://qiniu-image.qtshe.com/miniapp_publish_job.png" }, { pagePath: "/pages/canvas/index", name: "消息", icon: "/assets/img/xcx_b_job_normal.png", activeIcon: "/assets/img/xcx_b_job_active.png" }, { pagePath: "/pages/alipayMent/index", name: "我的", icon: "/assets/img/xcx_b_mine_normal.png", activeIcon: "/assets/img/xcx_b_mine_active.png" } ] } }, methods: { switchTab(e) { const {dataset: { item: { pagePath = '' }} = {}} = e.target my.switchTab({ url: pagePath }) } } });
尝试过:记录selected的值缓存在内存里,onInit的时候再赋值,结果为:点击后页面跳转了,底部样式却未更新(改为reLaunch跳转可以解决,但是tabbar闪烁严重)。那么如何做解决呢?查看第三步。
第三步:通过 getTabBar 接口获取 tabBar 组件实例。在tabbar的页面onShow里手动赋值:
JavaScript
onShow() { if (typeof this.getTabBar === "function" && this.getTabBar()) { this.getTabBar().setData({ selected: 1 // 这里是tabbar下标,每个tabbar页面都需要写一下。 }); } },
以上就是一个完整的自定义tabbar的实践效果,欢迎大家评论反馈问题。