CustomNavigationBar.vue 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. <script setup lang="ts">
  2. import { onMounted, ref } from 'vue'
  3. import { useRouter } from 'vue-router'
  4. const props = withDefaults(defineProps<Props>(), {
  5. title: '页面标题',
  6. showBack: true,
  7. backgroundColor: '#ffffff',
  8. textColor: '#ffffff',
  9. })
  10. const router = useRouter()
  11. // Props
  12. interface Props {
  13. title?: string
  14. showBack?: boolean
  15. backgroundColor?: string
  16. textColor?: string
  17. }
  18. // 导航栏高度
  19. const navBarHeight = ref('44px')
  20. const navBarTop = ref('44px')
  21. // const navigationBarEmptyHeight = ref('0px')
  22. // 返回按钮点击事件
  23. function handleBack() {
  24. router.back()
  25. }
  26. // 计算导航栏高度
  27. onMounted(() => {
  28. // #ifdef MP-WEIXIN
  29. uni.getSystemInfo({
  30. success: (res) => {
  31. const menuButtonInfo = uni.getMenuButtonBoundingClientRect()
  32. console.log('设备顶部信息:', res)
  33. console.log('胶囊信息:', menuButtonInfo)
  34. // 顶部导航栏高度 = 状态栏高度 + 胶囊的高度
  35. navBarHeight.value = `${menuButtonInfo.height}px`
  36. navBarTop.value = `${menuButtonInfo.top}px`
  37. // navigationBarEmptyHeight.value = `${menuButtonInfo.top + menuButtonInfo.height}px`
  38. }
  39. })
  40. // #endif
  41. })
  42. </script>
  43. <template>
  44. <view
  45. class="custom-navigation-bar"
  46. :style="{
  47. height: navBarHeight,
  48. top: navBarTop,
  49. backgroundColor: props.backgroundColor,
  50. color: props.textColor,
  51. }"
  52. >
  53. <!-- 返回按钮 -->
  54. <view v-if="props.showBack" class="nav-back-btn" @click="handleBack">
  55. <u-icon name="arrow-left" :color="props.textColor" size="18" class="back-icon" />
  56. </view>
  57. <!-- 标题 -->
  58. <view class="nav-title">
  59. {{ props.title }}
  60. </view>
  61. <!-- 占位元素,保持标题居中 -->
  62. <view v-if="props.showBack" class="nav-placeholder" />
  63. </view>
  64. <!-- 预留空间 用于导航栏占位 -->
  65. <!-- <view :style="{ height: navigationBarEmptyHeight }" /> -->
  66. </template>
  67. <style scoped>
  68. .custom-navigation-bar {
  69. position: fixed;
  70. left: 0;
  71. right: 0;
  72. display: flex;
  73. align-items: center;
  74. justify-content: center;
  75. /* padding: 0 16px; */
  76. box-sizing: border-box;
  77. z-index: 999;
  78. }
  79. .nav-back-btn {
  80. position: absolute;
  81. left: 16px;
  82. display: flex;
  83. align-items: center;
  84. justify-content: center;
  85. width: 44px;
  86. height: 100%;
  87. }
  88. .back-icon {
  89. font-size: 24px;
  90. }
  91. .nav-title {
  92. height: 100%;
  93. font-size: 18px;
  94. font-weight: 500;
  95. text-align: center;
  96. flex: 1;
  97. display: flex;
  98. align-items: center;
  99. justify-content: center;
  100. }
  101. .nav-placeholder {
  102. height: 100%;
  103. position: absolute;
  104. right: 16px;
  105. width: 44px;
  106. }
  107. </style>