# 自定义tabbar

# 一、默认设置

// app.json
"tabBar": {
  "color": "#86909C",
  "selectedColor": "#165DFF",
  "backgroundColor": "#f2f2f2",
  "borderStyle": "black",
  "list": [{
    "pagePath": "pages/index/index",
    "text": "首页",
    "iconPath": "./assets/images/home.png",
    "selectedIconPath": "./assets/images/home-selected.png"
  }, {
    "pagePath": "pages/my/index",
    "text": "我的",
    "iconPath": "./assets/images/my.png",
    "selectedIconPath": "./assets/images/my-selected.png"
  }]
},

# 二、自定义

正常在app.json中设置tabbar都是可以满足我们需要的,但是如果需要特殊样式的tabbar,如添加缩放、旋转、动画效果,默认的设置就无法满足我们的需要,所以我们可以 使用 custom 来自定义样式。 自定义tabbar (opens new window)

注意:

  • 需要自己定义一个组件来代替默认的
  • 默认与 tabBar 样式相关的接口将失效。
  • 每个 tab 页下的自定义 tabBar 组件实例是不同的,可通过自定义组件下的 getTabBar 接口,获取当前页面的自定义 tabBar 组件实例。 如需实现 tab 选中态,要在每个tabbar对应的页面,通过 this.getTabBar() 接口获取组件实例,并调用 setData 更新选中态的变量。

# 1、app.json配置

在tabBar中定义custom字段,其他相关字段也保留。

// app.json
"tabBar": {
  "custom": true,
  "color": "#86909C",
  "selectedColor": "#165DFF",
  "backgroundColor": "#f2f2f2",
  "borderStyle": "black",
  "list": [{
    "pagePath": "pages/index/index",
    "text": "首页",
    "iconPath": "./assets/images/home.png",
    "selectedIconPath": "./assets/images/home-selected.png"
  }, {
    "pagePath": "pages/my/index",
    "text": "我的",
    "iconPath": "./assets/images/my.png",
    "selectedIconPath": "./assets/images/my-selected.png"
  }]
},

# 2、自定义样式

在根目录新建一个组件custom-tab-bar,在根目录创建会被自动引入,如果在其他目录,还需要到对应的页面去引入组件,还要设置对应的状态。

custom-tab-bar/index.js
custom-tab-bar/index.json
custom-tab-bar/index.wxml
custom-tab-bar/index.wxss

custom-tab-bar/index.wxml

<!--miniprogram/custom-tab-bar/index.wxml-->
<cover-view class="tab-bar">
  <cover-view class="tab-bar-border"></cover-view>
  <cover-view wx:for="{{tabList}}" wx:key="index" class="tab-bar-item" data-path="{{item.pagePath}}" data-index="{{index}}" bindtap="switchTab">
    <cover-image src="{{selected === index ? item.selectedIconPath : item.iconPath}}"></cover-image>
    <cover-view style="color: {{selected === index ? selectedColor : color}}">{{item.text}}</cover-view>
  </cover-view>
</cover-view>

custom-tab-bar/index.json

{
  "component": true
}

custom-tab-bar/index.js

Component({
  data: {
    selected: 0,
    color: "#86909C",
    selectedColor: "#165DFF",
    tabList: [{
      pagePath: "/pages/index/index",
      iconPath: "../assets/images/home.png",
      selectedIconPath: "../assets/images/home-selected.png",
      text: "首页"
    }, {
      pagePath: "/pages/my/index",
      iconPath: "../assets/images/my.png",
      selectedIconPath: "../assets/images/my-selected.png",
      text: "我的"
    }]
  },

  methods: {
    switchTab(e) {
      console.log(this.getTabBar());
      const data = e.currentTarget.dataset
      const url = data.path
      wx.switchTab({
        url
      })
      this.setData({
        selected: data.index
      })
    }
  }
})

custom-tab-bar/index.wxml

.tab-bar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  height: 110rpx;
  background: white;
  display: flex;
  padding-bottom: env(safe-area-inset-bottom);
}

.tab-bar-border {
  background-color: rgba(0, 0, 0, 0.33);
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 1px;
  transform: scaleY(0.5);
}

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

.tab-bar-item cover-image {
  width: 27px;
  height: 27px;
}

.tab-bar-item cover-view {
  font-size: 10px;
}

# 3、设置tabbar对应的页面

如果只使用自定义组件会出现需要点击两次,切换状态才会改变,这是因为tabbar组件在每个页面都创建了一个对应组件,第一次切换切换当前的,但是在对应页面的状态没有被改变,所以在对应再点一下才会切换状态。要解决这个问题,需要在对应的页面手动把切换状态改为对应的值。

如在index/index.js中需要在onShow中设置,每个tabbar对应的页面都要设置


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