CustomNavigationBar.vue 2.4 KB

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