custom-tab-bar.vue 3.2 KB
Newer Older
Q
qiang 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
<template>
  <uni-tabbar v-if="hasTabBar" v-show="showTabBar">
    <div
      :style="{
        'flex-direction': direction === 'vertical' ? 'column' : 'row',
        backgroundColor: tabBar.backgroundColor,
      }"
      class="uni-tabbar"
    >
      <div
        v-for="(item, index) in tabBar.list"
        :key="item.pagePath"
        class="uni-tabbar__item"
        @click="switchTab(item, index)"
      >
        <div class="uni-tabbar__bd">
          <div
            v-if="showIcon && item.iconPath"
            :class="{ 'uni-tabbar__icon__diff': !item.text }"
            class="uni-tabbar__icon"
          >
            <img
              :src="
                getRealPath(
                  selectedIndex === index
                    ? item.selectedIconPath
                    : item.iconPath
                )
              "
            />
            <div
              v-if="item.redDot"
              :class="{ 'uni-tabbar__badge': !!item.badge }"
              class="uni-tabbar__reddot"
            >
              {{ item.badge }}
            </div>
          </div>
          <div
            v-if="item.text"
            :style="{
              color:
                selectedIndex === index ? tabBar.selectedColor : tabBar.color,
              fontSize: showIcon && item.iconPath ? '10px' : '14px',
            }"
            class="uni-tabbar__label"
          >
            {{ item.text }}
            <div
              v-if="item.redDot && (!showIcon || !item.iconPath)"
              :class="{ 'uni-tabbar__badge': !!item.badge }"
              class="uni-tabbar__reddot"
            >
              {{ item.badge }}
            </div>
          </div>
        </div>
      </div>
    </div>
  </uni-tabbar>
</template>

<script>
import { computed, ref, watch } from 'vue'
import { useRoute } from 'vue-router'
import { getRealPath } from '@dcloudio/uni-h5'
import { useTabBar } from '@dcloudio/uni-h5'

export default {
  name: 'CustomTabBar',
  props: {
    selected: {
      type: Number,
      default: 0
    },
    showIcon: {
      type: Boolean,
      default: true
    },
    direction: {
      type: String,
      default: 'horizontal'
    }
  },
  setup(props, { emit }) {
    const tabBar = useTabBar()
    const route = useRoute()
    const hasTabBar = computed(() => tabBar.list && tabBar.list.length)
    const selectedIndex = ref(props.selected)
    watch(() => props.selected, value => selectedIndex.value = value)
    watch(() => selectedIndex.value, value => tabBar.selectedIndex = value)
    watch(() => {
      const meta = route.meta
      return [meta.isTabBar, meta.route]
    }, ([isTabBar, pagePath]) => {
      if (isTabBar) {
        const index = tabBar.list.findIndex(item => pagePath === item.pagePath)
        if (index > -1) {
          selectedIndex.value = index
        }
      }
    })
    function switchTab(item, index) {
      selectedIndex.value = index
      const detail = {
        index,
        text: item.text,
        pagePath: item.pagePath,
      }
      emit('onTabItemTap', detail)
    }

    return {
      tabBar,
      getRealPath,
      selectedIndex,
      hasTabBar,
      showTabBar: true,
      switchTab,
    }
  }
}
</script>

<style>
</style>