TabBar.vue 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. <script setup lang="ts">
  2. import home from '@/static/image/tab-bar/home.png'
  3. import homeSelect from '@/static/image/tab-bar/home-select.png'
  4. import manual from '@/static/image/tab-bar/manual.png'
  5. import manualSelect from '@/static/image/tab-bar/manual-select.png'
  6. import my from '@/static/image/tab-bar/me.png'
  7. import mySelect from '@/static/image/tab-bar/me-select.png'
  8. import plan from '@/static/image/tab-bar/plan.png'
  9. import planSelect from '@/static/image/tab-bar/plan-select.png'
  10. interface BottomItem {
  11. name: string
  12. icon: string
  13. iconSelect: string
  14. url: string
  15. }
  16. const tabList: Ref<BottomItem[]> = ref([
  17. { name: '首页', icon: home, iconSelect: homeSelect, url: 'pages/home/index' },
  18. { name: '喂养计划', icon: plan, iconSelect: planSelect, url: 'pages/feed-plan/index' },
  19. { name: '养宠手册', icon: manual, iconSelect: manualSelect, url: 'pages/pet-manual/index' },
  20. { name: '我的', icon: my, iconSelect: mySelect, url: 'pages/me/index' },
  21. ])
  22. function handleTap(item: BottomItem) {
  23. uni.reLaunch({ url: `/${item.url}` })
  24. }
  25. function getCurrentPageUrl() {
  26. const pages = getCurrentPages() // Get the current pages stack
  27. const currentPage = pages[pages.length - 1] // Get the current page
  28. return currentPage.route // Return the route of the current page
  29. }
  30. const selectedIndex = computed(() => {
  31. return tabList.value.findIndex(item => item.url === getCurrentPageUrl())
  32. })
  33. const height = ref<number>(0)
  34. const instance = getCurrentInstance()
  35. if (instance) {
  36. const query = uni.createSelectorQuery().in(instance.proxy)
  37. query.select('#tabBar').boundingClientRect((data) => {
  38. if (data && !(Array.isArray(data))) {
  39. height.value = data.height as number
  40. }
  41. }).exec()
  42. }
  43. </script>
  44. <template>
  45. <view
  46. class="w-full"
  47. :style="{
  48. height: `${height}px`,
  49. }" t
  50. />
  51. <view id="tabBar" class="w-full p-1 fixed bottom-0 left-0 safe-area border-t-[0.5px] border-[#E7E7E7] bg-[#fff]">
  52. <view class="w-full flex gap-2">
  53. <view v-for="(item, index) in tabList" :key="index" class="flex flex-col items-center justify-center w-1/4" @tap="handleTap(item)">
  54. <image :src="selectedIndex === index ? item.iconSelect : item.icon" class="w-8 h-8" />
  55. <text
  56. class="text-3 mt-1"
  57. :class="selectedIndex === index ? 'text-primary' : 'text-default'"
  58. >
  59. {{ item.name }}
  60. </text>
  61. </view>
  62. </view>
  63. </view>
  64. </template>
  65. <style scoped>
  66. .safe-area{
  67. padding-bottom: env(safe-area-inset-bottom);
  68. }
  69. </style>