AppTabBar.vue 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. <template>
  2. <view class="tabbar safe-bottom">
  3. <view v-for="item in items" :key="item.key" class="tab-item press" @click="switchTab(item)">
  4. <view class="tab-icon" :class="{ active: active === item.key }">
  5. <text>{{ item.icon }}</text>
  6. <view v-if="Number(item.badge?.value ?? item.badge)" class="tab-badge">{{ item.badge?.value ?? item.badge }}</view>
  7. </view>
  8. <text class="tab-label" :class="{ active: active === item.key }">{{ item.label }}</text>
  9. </view>
  10. </view>
  11. </template>
  12. <script setup>
  13. import { onMounted, ref } from 'vue'
  14. import { fetchPendingApprovalCount } from '@/api/approval'
  15. const props = defineProps({ active: { type: String, default: 'home' } })
  16. // 待办角标:与首页 / 工作台同源,统一走审批中心
  17. const pendingCount = ref(0)
  18. onMounted(async () => {
  19. try {
  20. pendingCount.value = await fetchPendingApprovalCount()
  21. } catch (error) {
  22. pendingCount.value = 0
  23. }
  24. })
  25. const items = [
  26. { key: 'home', label: '首页', icon: '⌂', url: '/pages/home/index' },
  27. { key: 'work', label: '工作台', icon: '▦', url: '/pages/work/index', badge: pendingCount },
  28. { key: 'contacts', label: '通讯录', icon: '♙', url: '/pages/contacts/index' },
  29. { key: 'profile', label: '我的', icon: '○', url: '/pages/profile/index' },
  30. ]
  31. function switchTab(item) {
  32. if (item.key === props.active) return
  33. uni.reLaunch({ url: item.url })
  34. }
  35. </script>
  36. <style scoped lang="scss">
  37. .tabbar { position: fixed; z-index: 99; left: 0; right: 0; bottom: 0; height: 112rpx; display: flex; background: rgba(255,255,255,.98); border-top: 1rpx solid #e3e5e5; }
  38. .tab-item { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; padding-top: 8rpx; }
  39. .tab-icon { position: relative; height: 46rpx; min-width: 46rpx; display: flex; align-items: center; justify-content: center; color: #908f8f; font-size: 42rpx; font-weight: 500; }
  40. .tab-icon.active { color: #1677ff; }
  41. .tab-label { margin-top: 5rpx; color: #908f8f; font-size: 21rpx; }
  42. .tab-label.active { color: #1677ff; font-weight: 500; }
  43. .tab-badge { position: absolute; top: -6rpx; right: -15rpx; min-width: 28rpx; height: 28rpx; padding: 0 7rpx; border-radius: 16rpx; background: #ee4d4d; color: #fff; font-size: 18rpx; line-height: 28rpx; text-align: center; }
  44. @media (min-width: 800px) { .tabbar { max-width: 520px; left: 50%; transform: translateX(-50%); } }
  45. </style>