小程序使用有贊自定義tabbar

自定義tabBar

自定義 tabBar 可以讓開發(fā)者更加靈活地設(shè)置 tabBar 樣式,以滿足更多個(gè)性化的場(chǎng)景。詳細(xì)了解的話請(qǐng)參考官方文檔說明:自定義tabBar

官方文檔明確說明:
為了保證低版本兼容以及區(qū)分哪些頁面是 tab 頁,tabBar 的相關(guān)配置項(xiàng)需完整聲明,但這些字段不會(huì)作用于自定義 tabBar 的渲染,所有下圖的list是不用刪除的。

image.png
tabBar代碼文件

注意:添加的文件夾名字必須要和官方文件名字一樣,不能亂修改名字;然后右鍵文件夾選擇新建Component輸入index 即可。


image.png

只要我們?cè)赼pp.json中聲明了custom:true同時(shí)又創(chuàng)建了對(duì)應(yīng)的custom-tab-bar對(duì)應(yīng)的文件結(jié)構(gòu),微信小程序會(huì)自動(dòng)識(shí)別custom-tab-bar對(duì)應(yīng)的組件,把它的結(jié)構(gòu)渲染到頁面上,當(dāng)作我們的tabBar

image.png
編寫tabBar代碼

我們自定義 tabBar 可以通過 Vant 組件庫 里面的 tabBar 標(biāo)簽欄樣式來快速便捷的創(chuàng)建我們的tabBar代碼,如何配置 Vant 組件庫的具體過程就不在演示了,詳情請(qǐng)看一下如下這篇文章:
Vant組件庫的安裝及使用

image.png

image.png

自定義tabBar圖標(biāo)

Vant組件庫也為我們提供了具體的方法:可以通過 slot 自定義圖標(biāo),其中 icon slot 代表未選中狀態(tài)下的圖標(biāo),icon-active slot 代表選中狀態(tài)下的圖標(biāo)。

<van-tabbar-item info="3">
  <image slot="icon" src="/images/home.png" mode="aspectFit" style="width: 30px; height: 18px;"/>
  <image slot="icon-active" src="/images/home-active.png" mode="aspectFit" style="width: 30px; height: 18px;"/>
  首頁
</van-tabbar-item>
image.png

雖然我們可以自定義圖標(biāo),但是上面的自定義一個(gè)圖標(biāo)就要寫好多代碼,能不能有種方法可以簡(jiǎn)便的自定義我們的圖標(biāo),可以的。我們可以通過循環(huán)的形式將我們的tabbar-item給我們渲染出來。

首先我們需要將 list 里面的文件復(fù)制到自定義組件文件夾下 .js文件下的data里面:


image.png
// .wxml
<van-tabbar active="{{ active }}" bind:change="onChange">
  <van-tabbar-item wx:for="{{list}}" wx:key="index">
    <image slot="icon" src="{{item.iconPath}}" mode="aspectFit" style="width: 30px; height: 18px;"/>
    <image slot="icon-active" src="{{item.selectedIconPath}}" mode="aspectFit" style="width: 30px; height: 18px;" />
    {{item.text}}
  </van-tabbar-item>>
</van-tabbar>
image.png
渲染tabBar的數(shù)字徽標(biāo)

我們可以通過設(shè)置 info 屬性來渲染tabBar上的數(shù)字徽標(biāo),如下圖代碼圖片所示:

<!--custom-tab-bar/index.wxml-->
<van-tabbar active="{{ active }}" bind:change="onChange">
  <van-tabbar-item wx:for="{{list}}" wx:key="index" info="2">
    <image slot="icon" src="{{item.iconPath}}" mode="aspectFit" style="width: 30px; height: 18px;"/>
    <image slot="icon-active" src="{{item.selectedIconPath}}" mode="aspectFit" style="width: 30px; height: 18px;" />
    {{item.text}}
  </van-tabbar-item>>
</van-tabbar>

這樣做的結(jié)果雖然能達(dá)到數(shù)字徽標(biāo)效果的出現(xiàn),但顯然是把它寫死了,所以我們要進(jìn)行動(dòng)態(tài)的綁定,這里我們可以參考一下微信官方文檔的介紹。


image.png

image.png
// custom-tab-bar/index.wxml
<van-tabbar active="{{ active }}" bind:change="onChange">
  <van-tabbar-item wx:for="{{list}}" wx:key="index" info="{{item.info?item.info:''}}">
    <image slot="icon" src="{{item.iconPath}}" mode="aspectFit" style="width: 30px; height: 18px;"/>
    <image slot="icon-active" src="{{item.selectedIconPath}}" mode="aspectFit" style="width: 30px; height: 18px;" />
    {{item.text}}
  </van-tabbar-item>>
</van-tabbar>
 
// custom-tab-bar/index.js
import {storeBindingsBehavior} from '../miniprogram/miniprogram_npm/mobx-miniprogram-bindings/index'
import {store} from '../store/store'
Component({
  behaviors:[storeBindingsBehavior],
  storeBindings: {
    store,
    fields: {
      sum: "sum",
    },
    actions: {
    },
  },
  observers:{
    'sum':function(val){
      // console.log(val);
      this.setData({
       'list[1].info':val>0?val:0 //三元運(yùn)算符,如果數(shù)字徽標(biāo)的數(shù)值小于零,就賦值為0
      })
    }
  },
  /**
   * 組件的屬性列表
   */
  properties: {
 
  },
 
  /**
   * 組件的初始數(shù)據(jù)
   */
  data: {
    active:0,
    "list": [{
      "pagePath": "pages/home/home",
      "text": "首頁",
      "iconPath": "/images/home.png",
      "selectedIconPath": "/images/home-active.png"
    },
    {
      "pagePath": "pages/message/message",
      "text": "消息",
      "iconPath": "/images/message.png",
      "selectedIconPath": "/images/message-active.png",
      info:2
    },
    {
      "pagePath": "pages/contact/contact",
      "text": "聯(lián)系我們",
      "iconPath": "/images/contact.png",
      "selectedIconPath": "/images/contact-active.png"
    }]
  },
 
  /**
   * 組件的方法列表
   */
  methods: {
    onChange(event) {
      // event.detail 的值為當(dāng)前選中項(xiàng)的索引
      this.setData({ active: event.detail });
    },
  }
})
image.png
tabBar頁面切換及其樣式設(shè)置

我們將active引入到store實(shí)例對(duì)象當(dāng)中,來動(dòng)態(tài)的獲取頁面的索引值;在我們進(jìn)行自定義tabBar的時(shí)候切換頁面可能會(huì)出現(xiàn)閃爍問題,可自行百度,這里僅以舉例為主。

//.wxml
<van-tabbar active="{{active}}" bind:change="onChange">
  <van-tabbar-item wx:for="{{list}}" wx:key="index" info="{{item.info?item.info:''}}">
    <image slot="icon" src="{{item.iconPath}}" mode="aspectFit" style="width: 30px; height: 18px;"/>
    <image slot="icon-active" src="{{item.selectedIconPath}}" mode="aspectFit" style="width: 30px; height: 18px;" />
    {{item.text}}
  </van-tabbar-item>>
</van-tabbar>
 
//.js
// custom-tab-bar/index.js
import {storeBindingsBehavior} from '../miniprogram/miniprogram_npm/mobx-miniprogram-bindings/index'
import {store} from '../store/store'
Component({
  behaviors:[storeBindingsBehavior],
  storeBindings: {
    store,
    fields: {
      sum: "sum",
      active:'activeTabBarIndex',
    },
    actions: {
      updateActive:'updateActiveTabBarIndex'
    },
  },
  observers:{
    'sum':function(val){
      // console.log(val);
      this.setData({
       'list[1].info':val>0?val:0 //三元運(yùn)算符,如果數(shù)字徽標(biāo)的數(shù)值小于零,就賦值為0
      })
    }
  },
  /**
   * 組件的屬性列表
   */
  properties: {
 
  },
 
  /**
   * 組件的初始數(shù)據(jù)
   */
  data: {
    "list": [{
      "pagePath": "/pages/home/home",
      "text": "首頁",
      "iconPath": "/images/home.png",
      "selectedIconPath": "/images/home-active.png"
    },
    {
      "pagePath": "/pages/message/message",
      "text": "消息",
      "iconPath": "/images/message.png",
      "selectedIconPath": "/images/message-active.png",
      info:2
    },
    {
      "pagePath": "/pages/contact/contact",
      "text": "聯(lián)系我們",
      "iconPath": "/images/contact.png",
      "selectedIconPath": "/images/contact-active.png"
    }]
  },
 
  /**
   * 組件的方法列表
   */
  methods: {
    onChange(event) {
      // event.detail 的值為當(dāng)前選中項(xiàng)的索引
      // this.setData({ active: event.detail })
      this.updateActive(event.detail)
      wx.switchTab({
        url: this.data.list[event.detail].pagePath,
      })
 
    },
  }
})
 
//store.js
// 在這個(gè) JS 文件中,專門來創(chuàng)建 Store 的實(shí)例對(duì)象
import {observable,action} from '../miniprogram/miniprogram_npm/mobx-miniprogram/index'
 
export const store = observable({
  // 數(shù)據(jù)字段
  numA:1,
  numB:2,
  activeTabBarIndex:0,
  // 計(jì)算屬性
  get sum(){
    return this.numA + this.numB
  },
  // actions 函數(shù),專門來修改 store 中數(shù)據(jù)的值
  updateNum1:action(function(step){
    this.numA += step
  }),
  updateNum2:action(function(step){
    this.numB += step
  }),
  updateActiveTabBarIndex:action(function(index){
    this.activeTabBarIndex = index
  })
})
image.png

當(dāng)然我們也可以設(shè)置tabBar選中項(xiàng)的文本顏色:

image.png

image.png

其他具體的tabBar樣式設(shè)置可自行參考 Vant組件庫
原文傳送門

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容