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

41 篇文章 2 订阅
34 篇文章 19 订阅

最近开始在写一个零基础从0写一个失物招领小程序的系列视频,涉及到了自定义tabBar,也就是底部导航栏的内容。看了下我的博客似乎之前没更新过,所以给大家写一篇。

首先我们先去看下官方文档:

在这里插入图片描述
其实大致来说,可以总结为三点。

  1. 即便是自定义tabBar,也需要去app.json里进行配置文件的声明,也就是iconPathpagePathselectedIconPathtext这些。
  2. 需要自己写一个组件,来渲染tabBar
  3. 在更新选中态的时候,需要借助getTabBar来拿到tabBar实例

一步一步来。

配置tabBar

app.json

{
  "pages": [
    "pages/index/index",
    "pages/classify/classify",
    "pages/collection/collection",
    "pages/me/me"
  ],
  "window": {
    "backgroundColor": "#F6F6F6",
    "backgroundTextStyle": "light",
    "navigationBarBackgroundColor": "#ff70b4",
    "navigationBarTitleText": "失物招领",
    "navigationBarTextStyle": "white"
  },
  "tabBar": {
      "custom": true,
      "list": [
          {
             "iconPath": "images/index.png",
             "pagePath": "pages/index/index",
             "selectedIconPath": "images/index_fill.png",
             "text": "首页" 
          },
          {
            "iconPath": "images/classify.png",
            "pagePath": "pages/classify/classify",
            "selectedIconPath": "images/classify_fill.png",
            "text": "分类" 
         },
         {
            "iconPath": "images/collection.png",
            "pagePath": "pages/collection/collection",
            "selectedIconPath": "images/collection_fill.png",
            "text": "收藏夹" 
         },
         {
            "iconPath": "images/me.png",
            "pagePath": "pages/me/me",
            "selectedIconPath": "images/me_fill.png",
            "text": "我的" 
         }
      ]
  },
  "sitemapLocation": "sitemap.json",
  "style": "v2"
}

像使用原生tabBar一样,进行配置项的编写,但是额外注意的一点是,需要写一个custom属性,设置为true,这个是关键,表明自己需要自定义。

然后就进行第二步,自己写这个tabBar组件。

编写tabBar组件的内容

在写的时候要注意一点,不要写在pages里,也不要写在components里。

虽然自定义的tabBar是一个组件,但是比较特别,要独立新建一个文件夹,与pagescomponents同级。
在这里插入图片描述

这个文件夹的名字也比较讲究,根据官方文件的提示,文件夹的名字要命名为custom-tab-bar,如果不写这个名字,还要去改配置。

在这里插入图片描述

然后就可以去写这个组件的内容了,按照你自己的需求,进行jswxmlwxss的内容编写,和普通组件就没什么区别了。

custom-tab-bar/index.js

Component({
    data: {
        select: 0,
        list: [
            {
               iconPath: "/images/index.png",
               pagePath: "/pages/index/index",
               selectedIconPath: "/images/index_fill.png",
               text: "首页",
               type: 0
            },
            {
               iconPath: "/images/classify.png",
               pagePath: "/pages/classify/classify",
               selectedIconPath: "/images/classify_fill.png",
               text: "分类",
               type: 0
           },
           {
               type: 1,
           },
           {
              iconPath: "/images/collection.png",
              pagePath: "/pages/collection/collection",
              selectedIconPath: "/images/collection_fill.png",
              text: "收藏夹",
              type: 0,
           },
           {
              iconPath: "/images/me.png",
              pagePath: "/pages/me/me",
              selectedIconPath: "/images/me_fill.png",
              text: "我的",
              type: 0
           }
        ]
    },

    methods: {
        selectPage(e) {
            const { index, page, type } = e.currentTarget.dataset;
            if (index !== this.data.select && type === 0) {
                wx.switchTab({
                  url: page,
                })
            }
        }
    }
})

custom-tab-bar/index.json

{
    "component": true
}

custom-tab-bar/index.wxml

<view class="tabbar">
    <view 
        class="tabbar-item {{ select === index ? 'tabbar-select' : '' }}" wx:for="{{ list }}" 
        wx:key="index"
        data-page="{{ item.pagePath }}"
        data-index="{{ item.index }}"
        data-type="{{ item.type }}"
        bindtap="selectPage"
    >
        <block wx:if="{{ item.type === 0 }}">
            <image src="{{ select === index ?  item.selectedIconPath : item.iconPath }}"></image>
            <text>{{ item.text }}</text>
        </block>
        <block wx:else>
            <view class="publish">
            <image src="../images/add.png"></image>
            </view>
        </block>
    </view>
</view>

custom-tab-bar/index.wxss

.tabbar {
    width: 100%;
    display: flex;
    background-color: #fff;
    position: fixed;
    bottom: 0;
    padding-bottom: env(safe-area-inset-bottom);
    padding-top: 10rpx;
    z-index: 9999;
}

.tabbar-item {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}

.tabbar-item image {
    width: 50rpx;
    height: 50rpx;
}

.tabbar-item text {
    font-size: 26rpx;
    margin-top: 10rpx;
}

.tabbar-item .publish {
    width: 65rpx;
    height: 65rpx;
    background-color: #ff90ba;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: auto;
}

.tabbar-select {
    color: #ff90ba;
}

需要注意几点就是:

  1. index.json里要设置componenttrue
  2. index.js里的内容格式与常规的组件一样
  3. 因为是自定义组件,要注意的是,在写组件最外层的标签样式时,如果不写padding-bottomtabBar的大部分内容会被手机的底部遮挡住。
    在这里插入图片描述
    那么问题就来了,这个padding-bottom写多少合适呢,因为不同手机、不同终端这个底部遮挡区域都是不一样的。微信小程序为我们内置了这个值,env(safe-area-inset-bottom),将padding-bottom设置为这个值,它就会根据终端动态的计算一个合理的值。
    在这里插入图片描述
    这样就很好了。

切换tabBar的选中态

然后还剩最后一个步骤,就是在跳转其它tabBar页面的时候,选中态的切换,因为我们在组件内声明了select变量,其实动态的改这个值就可以。

但是不能直接在组件内进行更改,要在跳转页面的过程中进行更改。

比如select默认是0,代表A页面,当我们从A页面跳转到B页面的时候,我们就需要将select赋值为1,当然这也不是绝对的,这要取决于你组件内选中态的切换逻辑是怎么样的。

比如我的:

       list: [
            {
               iconPath: "/images/index.png",
               pagePath: "/pages/index/index",
               selectedIconPath: "/images/index_fill.png",
               text: "首页",
               type: 0
            },
            {
               iconPath: "/images/classify.png",
               pagePath: "/pages/classify/classify",
               selectedIconPath: "/images/classify_fill.png",
               text: "分类",
               type: 0
           },
           {
               type: 1,
           },
           {
              iconPath: "/images/collection.png",
              pagePath: "/pages/collection/collection",
              selectedIconPath: "/images/collection_fill.png",
              text: "收藏夹",
              type: 0,
           },
           {
              iconPath: "/images/me.png",
              pagePath: "/pages/me/me",
              selectedIconPath: "/images/me_fill.png",
              text: "我的",
              type: 0
           }
        ]

我这样来声明的话,select和页面的对应关系就是:

select: 0 = index页面
select: 1 = classify页面
select: 3 = collection页面
select: 4 = me页面

那么问题就来了,我如何在页面切换的时候,改自己这个自定义tabBar内的值呢。

系统为我们提供了getTabBar方法,你输出一下this,就可以看到这个方法,这个方法会返回给我们自定义tabBar的组件实例,也就是说,可以这样写:

	this.getTabBar().setData({
		select: xxx
	})

有了这个方法之后,我们在所有tabBar涉及到的页面的onShow方法里,进行执行上述代码即可。

比如在首页的index.js里:

  onShow: function () {
    if (typeof this.getTabBar === 'function' && this.getTabBar()) {
        this.getTabBar().setData({
            select: 0
        })
    }
  },

进行if判断的原因是进行兼容,避免报错。在getTabBar这个方法存在的前提下,再进行操作。

在分类页的index.js里:

  onShow: function () {
    if (typeof this.getTabBar === 'function' && this.getTabBar()) {
        this.getTabBar().setData({
            select: 1
        })
    }
  },

至此,我们就完成了,自定义tabBar底部导航栏的全部内容,大致分为三步:在app.json里进行tabBar的配置、编写组件内容、通过getTabBar方法切换选中态。

工种号:Code程序人生

  • 8
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CreatorRay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值