再谈小程序自定义底部导航

小程序自定义tabBar再探索

前言

最近有很多微信开发者朋友在QQ上加我好友,忽然意识到大家对微信自定义底部导航栏需求还是挺大的,故而再次整理下底部导航栏组件开发思路。和之前的文章还是有些区别,并且底部导航栏组件增加新的特性以及一些优化开发体验的骚操作。

技术选型

与之前不同,现在我们有两种方法实现自定义底部导航栏,因为小程序在2.5.0开始支持自定义底部导航栏了戳此处看文档,所以我们现在的可选方案为:

  • 通过HideTabBar接口hack底部导航栏
  • 通过小程序支持配置实现底部导航栏

下面根据两种方式都讲讲

通过HideTabBar接口hack底部导航栏

实现思路

首先我们先了解下微信的路由api和微信的路由机制,微信一共提供了5个路由api:wx.navigateTowx.redirectTowx.switchTabwx.navigateBackwx.reLaunch,具体文档位于https://developers.weixin.qq.com/miniprogram/dev/api/ui-navigate.html

其中我们用哪个呢?很显然wx.switchTab很合我们的口味,因为他的切换效果是没有推入推出动画的,更符合我们的习惯,那使用他的前提是我们需要在app.json文件中配置tabBar属性,而只要一配置了tabBar属性,系统原生的导航栏就出现了,幸好微信有一个隐藏原生导航栏的api:wx.hideTabBar。看到这里相信聪明的同学已经知道了实现思路,就是隐藏掉原生的然后自己去实现一个导航栏贴在最下面。

使用方法

源码地址

本次代码拷贝之后可以直接使用,具体操作如下

  1. 复制components/custom-tab-bar文件夹到你的项目
  2. 在app.json中设置usingComponents对象
  3. 在tab页面的wxml最后追加<custom-tab-bar></custom-tab-bar>

即可观察效果

支持的特性

  • 无需额外配置,甚至不用传参,自动读取app.jsontabBar的配置
  • 使用wx.showTabBarRedDot方法可以设置红点
  • 可以自定义样式,摆脱微信限制(如borderStyle仅支持black/white的限制)
  • 可以定制个性化逻辑
  • 兼容iphoneX,底部自动留空

关键代码介绍

tabBar配置的获取

看过之间博客的同学知道,之前是需要一个额外的route.js文件的,来获取tabBar的配置,原因是小程序js无法读取json文件。随着知(sao)识(cao zuo)掌握增多,发现了更加方便的办法:我们可以通过__wxConfig全局对象的tabBar属性去查看app.json设置。所以我们在组件中直接这样定义:

const fixListConfig = function(item, index) {
  const result = {}; // 使用新对象,类似浅拷贝
  result.pagePath = "/" + item.pagePath.replace(/.html$/g, "");
  result.iconPath = item.iconData
    ? "data:image/png;base64," + item.iconData
    : "/" + item.iconPath;
  result.selectedIconPath = item.selectedIconData
    ? "data:image/png;base64," + item.selectedIconData
    : "/" + item.selectedIconPath;
  result.idx = index;
  result.redDot = false;
  result.text = item.text;
  return result;
};
const _tabBar = __wxConfig.tabBar;

Component({
  data: {
    activeIdx: -1,
    config: _tabBar,
    list: _tabBar.list.map(fixListConfig)
  },
});

其中list就是我们tab页面列表,tabBar里面还包括了我们定义的一些样式,比如selectColor之类的,因为格式并不是直接拿来就能用,所以我们用map对数据进行了修改和浅拷贝。

此处还有一个坑,部分真机上小程序配置中的图标会变成base64格式的,所以需要做兼容。

上面代码不是难点,关键在于__wxConfig对象,大家可以在微信开发工具控制台执行this.__wxConfig看看里面的内容,相信能对你有所启发。

当前页的判断

相信大家都用过getCurrentPages()这个全局函数,我们也是通过它来获取当前页面的路由然后将其标记为active状态。本着自己的事情自己做的原则,我利用自定义组件的pageLifetimes功能,实现了内部判断当前页,具体代码如下:

pageLifetimes: {
    show() {
      const pages = getCurrentPages();
      const page = pages[pages.length - 1];
      const route = page.__route__;
      const idx = this.data.list.find(item => item.pagePath === `/${route}`)
        .idx;
      if (this.data.activeIdx !== idx) {
        this.setData({
          activeIdx: idx
        });
      }
    }
}

注意pageLifetimes特性在基础库2.2.3以上支持,目前没什么问题,其实外面传值写死也是ok的,毕竟每个页面是一个单独的组件。

使用css兼容iPhone X(强烈建议了解)

此处一需一行代码

.tab-bar{
    padding-bottom: env(safe-area-inset-bottom);
}

这个方法不光可用于小程序,也可用于移动端,网上有很多介绍他的文章,比如网页适配 iPhoneX,就是这么简单

修改wx接口注入自己的代码逻辑

上面特性中提到了,我们可以使用wx.showTabBarRedDot方法设置我们的redDot,也可以打开上面的小程序微码查看效果。这个是利用Object.defineProperty方法实现的,具体代码可以看custom-tab-bar/extraFun.js文件查看。这块就不再详述了,大家想了解的可以直接阅读源码,如果有疑问可以单独联系我。

通过小程序支持配置实现底部导航栏

现在,我们来聊聊为什么不用小程序支持的配置方法实现底部导航栏。

使用方法

现在我们根据文档进行改造,在app.jsontabBar对象中增加"custom":true,并在根目录下增加custom-tab-bar/index组件。之后的开发就和上面差不多了,我们写组件实现期望的效果。

两者的区别

为了描述方便,我们将之前提到的方法称为方法一,小程序配置的称之为方法二。方法一的组件是在page里面的,方法二的组件是和page并列的关系,如图所示:

这个对我们有什么影响吗,就我目前观察,有几个问题

  • 某些情况下会引起bug,当我们打开一个非tab页面的时候,还是会显示底部导航栏。(最严重问题,会有bug)
  • 无法使用全局定义的样式,哪怕组件激活了addGlobalClass选项之后(不了解addGlobalClass的同学见文档:使组件接受全局样式
  • 需要基础库>=2.5.0,有部分用户无法覆盖。当前版本分布情况

总结

最后还是感谢大家能坚持读完,本人作为一个理科生,文笔太差,有许多想法表达不出来,真是吃了没文化的亏。文中介绍的两种方法,我目前还是只会考虑第一种,以后会一直观望微信配置法,相信当它完善的那天我会毫不犹豫的使用,毕竟跟着标准才能走的更远。如果对本代码或在开发过程中遇到什么问题,欢迎与我交流858582381~

另外,下一步打算分享自定义头部标题栏,不知道大家对此是否期待。

原文地址:https://www.cnblogs.com/ljybill/p/10419706.html

时间: 2024-10-14 10:36:56

再谈小程序自定义底部导航的相关文章

微信小程序-自定义底部导航

代码地址如下:http://www.demodashi.com/demo/14258.html 一.前期准备工作 软件环境:微信开发者工具 官方下载地址:https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/download.html 1.基本需求. 实现用户自定义底部导航 2.案例目录结构 二.程序实现具体步骤 1.自定义nav.wxml代码 <template name="nav"> <view class=&quo

小程序自定义底部导航

这个方法比较简单,虽然有一些延迟,但也算是解决了一半自定义的问题. 首先在pages同级目录下创建tabbar.wxml文件, <template name="tabBar"> <view class="tab-bar" style="color: {{tabBar.color}}; background: {{tarBar.backgroundColor}}; {{tabBar.position=='top'? 'top: 0' : '

使用wepy开发微信小程序的底部导航

前言: 最近公司在做一个微信小程序的项目,用的是类似于vue的wepy框架.我也借此机会学习和实践一下. 小程序官方文档:https://developers.weixin.qq.com/miniprogram/dev/ wepy官方文档:https://tencent.github.io/wepy/document.html#/ wepy小程序项目初始化:wepy小程序入门之项目初始化 今天的目标是开发微信小程序的底部导航 效果图: 1.打开编辑器(我用的是vscode),然后打开微信开发者工

微信小程序自定义顶部导航demo

注释:自定义导航需要自备相应图片 一.设置自定义顶部导航 Navigation是小程序的顶部导航组件,当页面配置navigationStyle设置为custom的时候可以使用此组件替代原生导航栏. 1.全局顶部导航自定义,在app.json的“window”里添加"navigationStyle": "custom" 2.只在某一个页面自定义顶部导航,在该页面的json文件里添加"navigationStyle": "custom&qu

小程序自定义底部tab

首页wxml的代码: <view class="nav" hover-class="none"> <view class="index" bindtap="fresh"> <image class="navbottomicon" src="{{homeOr?srcactive :src}}"></image> <text class=

微信小程序(底部导航的实现)

详情请看官方文档介绍: https://mp.weixin.qq.com/debug/wxadoc/dev/framework/config.html 在根目录配置文件中配置底部导航: 注意: tabBar中list是一个数组,最少配置2个,做多5个tab,tab按数组的顺序排序. tabBar配置属性说明: color:tab上文字默认的颜色 selectedColor:文字选中时的颜色 backgroundColor:tab背景色 …… position:可选值bottom,top,需要注意

小程序自定义头部导航栏

首先先编写导航栏组件 写法一 1你要自定义导航栏首先你要知道导航栏的高度,导航栏由状态栏和胶囊按钮构成通过Object wx.getMenuButtonBoundingClientRect()可以拿到胶囊按钮的信息,通过wx.getSystemInfo可以拿导航栏信息 整个导航栏高度 = statausBarHeight + height + (top-statausBarHeight )*2: 还有一种写法是状态栏加上44px当做导航栏的高度 之前公司项目用的第二种所以我也用了这种 直接上代码

微信小程序 关于底部导航设置

在app.json 中添加 "tabBar": { "color":"#ffffff", "borderStyle":"white", "selectedColor":"#d81e06", "backgroundColor":"#245685", "list": [{ "pagePath"

小程序自定义单页面、全局导航栏

摘要: 小程序开发技巧. 作者:小白 原文:小程序自定义单页面.全局导航栏 Fundebug经授权转载,版权归原作者所有. 需求 产品说小程序返回到首页不太方便,想添加返回首页按钮,UI说导航栏能不能设置背景图片,因为那样设计挺好看的. 需求分析并制定方案 这产品和UI都提需求了,咱也不能反驳哈,所以开始调研,分析可行性方案:1.可以添加悬浮按钮.2.自定义导航栏. 添加悬浮按钮,是看起来是比较简单哈,但是感觉不太优雅,会占据页面的空间,体验也不太好.所以想了下第二种方案,自定义导航栏既可以实现