custom-tab-bar.vue 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. <template>
  2. <uni-tabbar v-if="hasTabBar" v-show="showTabBar">
  3. <div
  4. :style="{
  5. 'flex-direction': direction === 'vertical' ? 'column' : 'row',
  6. backgroundColor: tabBar.backgroundColor,
  7. }"
  8. class="uni-tabbar"
  9. >
  10. <template v-for="(item, index) in tabBar.list" :key="item.pagePath">
  11. <div
  12. v-if="item.visible !== false"
  13. class="uni-tabbar__item"
  14. @click="switchTab(item, index)"
  15. >
  16. <div class="uni-tabbar__bd">
  17. <div
  18. v-if="showIcon && item.iconPath"
  19. :class="{ 'uni-tabbar__icon__diff': !item.text }"
  20. class="uni-tabbar__icon"
  21. >
  22. <img
  23. :src="
  24. getRealPath(
  25. selectedIndex === index
  26. ? item.selectedIconPath
  27. : item.iconPath
  28. )
  29. "
  30. />
  31. <div
  32. v-if="item.redDot"
  33. :class="{ 'uni-tabbar__badge': !!item.badge }"
  34. class="uni-tabbar__reddot"
  35. >
  36. {{ item.badge }}
  37. </div>
  38. </div>
  39. <div
  40. v-if="item.text"
  41. :style="{
  42. color:
  43. selectedIndex === index ? tabBar.selectedColor : tabBar.color,
  44. fontSize: showIcon && item.iconPath ? '10px' : '14px',
  45. }"
  46. class="uni-tabbar__label"
  47. >
  48. {{ item.text }}
  49. <div
  50. v-if="item.redDot && (!showIcon || !item.iconPath)"
  51. :class="{ 'uni-tabbar__badge': !!item.badge }"
  52. class="uni-tabbar__reddot"
  53. >
  54. {{ item.badge }}
  55. </div>
  56. </div>
  57. </div>
  58. </div>
  59. </template>
  60. </div>
  61. </uni-tabbar>
  62. </template>
  63. <script>
  64. import { computed, ref, watch } from 'vue'
  65. import { useRoute } from 'vue-router'
  66. import { getRealPath } from '@dcloudio/uni-h5'
  67. import { useTabBar } from '@dcloudio/uni-h5'
  68. export default {
  69. name: 'CustomTabBar',
  70. props: {
  71. selected: {
  72. type: Number,
  73. default: 0
  74. },
  75. showIcon: {
  76. type: Boolean,
  77. default: true
  78. },
  79. direction: {
  80. type: String,
  81. default: 'horizontal'
  82. }
  83. },
  84. setup(props, { emit }) {
  85. const tabBar = useTabBar()
  86. const route = useRoute()
  87. const hasTabBar = computed(() => tabBar.list && tabBar.list.length)
  88. const selectedIndex = ref(props.selected)
  89. watch(() => props.selected, value => selectedIndex.value = value)
  90. watch(() => selectedIndex.value, value => tabBar.selectedIndex = value)
  91. watch(() => {
  92. const meta = route.meta
  93. return [meta.isTabBar, meta.route]
  94. }, ([isTabBar, pagePath]) => {
  95. if (isTabBar) {
  96. const index = tabBar.list.findIndex(item => pagePath === item.pagePath)
  97. if (index > -1) {
  98. selectedIndex.value = index
  99. }
  100. }
  101. })
  102. function switchTab(item, index) {
  103. selectedIndex.value = index
  104. const detail = {
  105. index,
  106. text: item.text,
  107. pagePath: item.pagePath,
  108. }
  109. emit('onTabItemTap', detail)
  110. }
  111. return {
  112. tabBar,
  113. getRealPath,
  114. selectedIndex,
  115. hasTabBar,
  116. showTabBar: true,
  117. switchTab,
  118. }
  119. }
  120. }
  121. </script>
  122. <style>
  123. </style>