1. 程式人生 > 其它 >UNI-APP 自定義微信小程式底部導航欄

UNI-APP 自定義微信小程式底部導航欄

本文只針對於微信小程式的自定義底部導航欄;
PS:可能在進入小程式後,首次點選tabBar會出現閃爍的情況;不能接受的就還是乖乖的用回預設吧!

需求

在開發記賬APP時,感覺微信小程式預設的tabBar功能很簡單,而且不能進行美化,作為強迫症的我,不能忍,直接摟它;
我需要達到的效果如下:

  • 中間的按鈕凸起;
  • 中間的按鈕點選時需要跳轉二級頁面;

方案

當然,我們以UNI-APP官方的案例為主,先看一下官方怎麼做的:UNI-APP 自定義 tabBar
官方文件也是描述了一下,具體實現也還是需要使用wxml、wxss進行實現,並且需要將自定義tabBar放在專案根目錄下的custom-tab-bar資料夾下;最終方案也是跳到了微信社群:

微信小程式 自定義 tabBar

實現

1、修改配置page.json檔案

新增custom欄位,並賦值true,表示這裡我們使用的是自定義的tabBar;
此時,我們這裡的配置資料就不生效了;

2、新增自定義tabBar

a、建立資料夾及自定義tabBar檔案(index.js、index.json、index.wxml、index.wxss)

針對我上述圖中的效果,程式碼如下:

index.js
Component({
  data: {
    selected: 0,
    color: "#D1D1D1",
    selectedColor: "#A6B1E1",
    list: [{
      "pagePath": "/pages/index/index",
      "text": "賬目"
    },
    {
      "pagePath": "/pages/profile/index",
      "text": "我的"
    }]
  },
  attached() {
  },
  methods: {
    switchTab(e) {
      const data = e.currentTarget.dataset
      const url = data.path
      wx.switchTab({ url })
      this.setData({
        selected: data.index,
      })
    },
    // 此處需要針對中間的tabBar跳轉到二級頁面,而不是使用switchTab
    toadd() {
      wx.navigateTo({ url: '/pages/bill/edit' })
    }
  }
})
index.json
{
  "component": true
}
index.wxml
<!--miniprogram/custom-tab-bar/index.wxml-->
<view class="tab-bar">
  <view wx:for="{{list}}" wx:key="index" class="tab-bar-item {{item.bulge?'bulge':''}}" data-path="{{item.pagePath}}" data-index="{{index}}" bindtap="switchTab">
    <view  wx:if="item.bulge" class="tab-bar-bulge tab-bar-view"></view>
    <image style="display: {{item.bulge? 'block' : 'none'}};" class="image" src="{{selected === index ? item.selectedIconPath : item.iconPath}}"></image>
    <view  wx:if="{{item.text}}" style="color: {{selected === index ? selectedColor : color}}" class="tab-bar-view">{{item.text}}</view>
  </view>
  <view class="bulge"  bindtap="toadd">
    <view class="background">
      <image class="image" src="/static/assets/tabbar/plus.png"></image>
    </view>
  </view>
</view>
index.wxss
.tab-bar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  height: 48px;
  display: flex;
  line-height: 1.2;
  padding-bottom: env(safe-area-inset-bottom);
  background: white;

}

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

.bulge {
  position: absolute;
  left: 50%;
  right: 50%;
  transform: translate(-50%);
  top: -12px;
  height: 80px;
  width: 60px;
  display: flex;
  justify-content: center;
}

.bulge .background{
  background: #A6B1E1;
  width: 45px;
  height: 45px;
  border-radius: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.bulge .background .image{
  width: 20px;
  height: 20px;
}

.tab-bar-item .tab-bar-view {
  font-size: 13px;
  font-weight: bold;
}

3、對tabBar指向頁面的onShow邏輯處理

實際開發中,如果不進行此項處理則會導致點選tabBar時出現奇怪的問題:點選另外一個bar時,上一個bar才會處於被選中狀態;

解決該問題就要在每個tabBar指向頁面的onShow新增如下程式碼:

onShow() {
    if (typeof this.$scope.getTabBar === 'function' &&
        this.$scope.getTabBar()) {
        this.$scope.getTabBar().setData({
            // 當前頁面對應的tab index
            selected: 0,
        })
    }
}

但是,我們需要優雅點,使用mixins進行混入,達到一個function隨處使用,且本文使用的時區域性混入,需要在使用到的頁面進行混入,程式碼如下:

根目錄下建立mixins資料夾,並建立tabbar.js
export const mixin = {
    methods: {
        setTabBarIndex(index) {
            if (typeof this.$scope.getTabBar === 'function' &&
                this.$scope.getTabBar()) {
                this.$scope.getTabBar().setData({
                    selected: index,
                })
            }
        }
    }
}
在需要混入的頁面進行配置
// 引入混入js
import { mixin } from "@/mixins/tabbar.js";

export default {
  mixins: [mixin], //混入js檔案
  onShow() {
    this.setTabBarIndex(0);
  },
}

需要注意

  • 在UNI-APP編譯後,生成了dist資料夾後再進行此項更改,且直接熱更新使用的話會出現兩個tabBar且重疊的情況,此時需要刪除dist,並重新生成;