H5版基於uni-app實現自定義底部tabbar效果(支持底部圖標選中時的漸變效果)

首先聲明部分代碼轉載自 uniapp自定義tabbar導航解析

我自己又在基礎上添加了一些功能,如實現tab的數字角標、tab頁面跳轉、tabbar選中狀態的圖標高亮漸變。

效果如下:
在這裏插入圖片描述

tabbar已經抽離成組件了。

tabbar組件代碼

<template>
  <view class="tab-bar-container">
    <block v-for="(item, index) in tabList" :key="index">
      <view class="navigator" :class="[currentTabIndex === index ? 'on' : '']" @tap="switchTab(item, index)">
        <view class="icon">
          <text class="icon-style iconfont" :class="[currentTabIndex === index ? [item.iconActive, 'height-light'] : item.icon]" :style="[currentTabIndex === index ? '' : { color: color }]"></text>
        </view>
        <view class="text" :style="[currentTabIndex === index ? { color: tintColor } : { color: color }]">{{ item.text }}</view>
        <!-- 消息數字角標 -->
        <uni-badge class="num-badge" v-if="item.badgeNum" size="small" type="error" :text="item.badgeNum" @click="handleBadge(index)"></uni-badge>
      </view>
    </block>
  </view>
</template>

<script>
import uniBadge from "@/components/uni-badge/uni-badge.vue"
export default {
  components: {
    uniBadge
  },
  props: {
    current: { 
      type: [Number, String],
      default: 0
    },
    backgroundColor: {
      type: String,
      default: '#fbfbfb'
    },
    color: {
      type: String, 
      default: '#999'
    },
    tintColor: { 
      type: String, 
      default: '#3768FC'
    }
  },
  data() {
    return {
      // 數字角標
      /*
       * icon 默認圖標
       * iconActive 選中圖標
       * text 文字信息
       * path 頁面路徑
       */
      tabList: [
        {
          icon: 'icon-home',
          iconActive: 'icon-home-hl',
          text: '首頁',
          path: '../index/index'
        },
        {
          icon: 'icon-tidings',
          iconActive: 'icon-tidings-hl',
          text: '消息',
          path: '../message/message',
          badgeNum: 2
        },
        {
          icon: 'icon-mailList',
          iconActive: 'icon-mailList-hl',
          text: '通訊錄',
          path: '../contacts/contacts'
        },
        {
          icon: 'icon-workPlatform',
          iconActive: 'icon-workPlatform-hl',
          text: '工作臺',
          path: '../workPlatform/workPlatform'
        },
        {
          icon: 'icon-user',
          iconActive: 'icon-user-hl',
          text: '我的',
          path: '../my/my'
        }
      ],
      currentTabIndex: this.current
    };
  },
  methods: {
    // 切換頁面
    switchTab(tab, index) {
      this.currentTabIndex = index;
      
      if (this.currentTabIndex === index && tab.badgeNum) {
        this.$nextTick(function(){
          this.$set(this.tabList[index], 'badgeNum', 0)
        })
      }
      
      this.$emit('click', {
        path: tab.path,
        index
      });
    },
    // 點擊數字角標
    handleBadge(index) {
      // if (this.currentTabIndex === index) {
      //   this.badgeNum = 0
      // }
    }
  }
};
</script>

<style scoped lang="scss">
.tab-bar-container {
  position: fixed;
  left: 0;
  bottom: 0;
  z-index: 999;
  width: 100%;
  height: 50px;
  box-shadow: 0 0 6px 0 rgba(0,0,0,0.12);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 50rpx;
  box-sizing: border-box;
  background-color: #fff;
  
  
  .navigator {
    height: 100%;
    width: 80rpx;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    position: relative;
    
    .icon-style {
      font-size: 20px;
    }
    
    /* 選中圖標的高亮樣式 */
    .height-light {
      background: linear-gradient(137deg, #507EFF 26%, #2A56F7 71%, #193EEE 100%);
      -webkit-background-clip: text;
      color: transparent;
    }
    
    .text {
      font-size: 24rpx;
    }
    
    .num-badge {
      position: absolute;
      top: 0;
      right: -26rpx;
    }
  }
}
</style>

tabbar組件的使用

<template>
  <view class="container">
    <text class="title">{{ name }}</text>

    <!-- 自定義tabbar -->
    <tab-bar :current="currentTabIndex" backgroundColor="#FFFFFF" color="#999" tintColor="#3768FC" @click="tabClick"></tab-bar>
  </view>
</template>

<script>
export default {
  data() {
    return {
      name: '消息',
      // 當前tab高亮索引
      currentTabIndex: 1
    };
  },
  methods: {
    // 進行tab頁跳轉
    tabClick(obj) {
      this.currentTabIndex = obj.index
      uni.redirectTo({
         url: obj.path
      })
    }
  }
};
</script>

<style>
.container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.title {
  font-size: 24rpx;
  color: #8f8f94;
}
</style>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章