tabbar-evo.vue 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. <script lang="ts" setup>
  2. import { currRoute, getIsTabbar } from '@/utils'
  3. import { onMounted, ref } from 'vue'
  4. const props = defineProps({
  5. items: {
  6. type: Array as PropType<
  7. {
  8. title: string
  9. icon?: string
  10. iconPath: string
  11. selectedIconPath: string
  12. path: string
  13. hiddenTitle?: boolean
  14. }[]
  15. >,
  16. default: () => [],
  17. },
  18. currentPath: {
  19. type: String,
  20. default: '',
  21. },
  22. fixed: {
  23. type: Boolean,
  24. default: false,
  25. },
  26. safeAreaInsetBottom: {
  27. type: Boolean,
  28. default: false,
  29. },
  30. })
  31. const emits = defineEmits<{ click: [path: string] }>()
  32. const safeAreaInsets = ref({ bottom: 0 })
  33. const tabbar = ref<HTMLElement | undefined>()
  34. const handleClick = (path: string) => {
  35. // uni.switchTab({ url: path })
  36. emits('click', path)
  37. }
  38. onMounted(async () => {
  39. if (props.safeAreaInsetBottom) {
  40. // uniapp 获取safeAreaInsetBottom
  41. const res = await uni.getSystemInfoSync()
  42. safeAreaInsets.value = res.safeAreaInsets
  43. // 获取到tabbar的dom计算过的margin
  44. if (tabbar.value) {
  45. tabbar.value.style.marginBottom = `${safeAreaInsets.value.bottom + 14}px`
  46. }
  47. }
  48. })
  49. </script>
  50. <template>
  51. <div>
  52. <!-- <wd-tabbar fixed shape="round" safeAreaInsetBottom>
  53. <template v-for="it of items" :key="it.id">
  54. <wd-tabbar-item :title="it.title" :icon="it.icon">
  55. <template #icon v-if="it.iconPath">
  56. <wd-img round height="40rpx" width="40rpx" :src="it.iconPath"></wd-img>
  57. </template>
  58. </wd-tabbar-item>
  59. </template>
  60. </wd-tabbar> -->
  61. <div>
  62. <div
  63. ref="tabbar"
  64. :class="[fixed ? 'fixed bottom-0 left-0 right-0' : '']"
  65. class="m-3.5 h-[60px] bg-white/70 rounded-[60px] border border-white backdrop-blur-[25px] flex items-center justify-around"
  66. >
  67. <template
  68. v-for="({ iconPath, selectedIconPath, title, hiddenTitle, path }, i) in items"
  69. :key="i"
  70. >
  71. <div class="flex flex-col items-center justify-center" @click="handleClick(path)">
  72. <wd-img
  73. round
  74. :height="hiddenTitle ? 40 : 22"
  75. :width="hiddenTitle ? 40 : 22"
  76. :src="currentPath === path ? selectedIconPath : iconPath"
  77. ></wd-img>
  78. <span
  79. class="mt-1 text-center text-[10px] font-normal font-['PingFang SC'] leading-none"
  80. :class="[currentPath === path ? 'text-black' : 'text-[#8c8c8c]']"
  81. v-if="!hiddenTitle"
  82. >
  83. {{ title }}
  84. </span>
  85. </div>
  86. </template>
  87. </div>
  88. </div>
  89. </div>
  90. </template>