具體代碼
<template><view class="nav-wrapper-container" :style="'height:'+navBarHeight +'px'"><view class="nav-status-container" :style="'height:'+navstatusBarHeight +'px;'" /><view v-if="isCustom" class="nav-content-container" :style="'height:'+navContentHeight +'px;'"><slot name="left"></slot><slot name="middle"> </slot><view :style="'width:'+navPaddingRight+'px;'+'height:40px'"></view></view><view v-else class="nav-content-container" :style="'height:'+navContentHeight +'px;'"><image v-if="!isInTab" class="nav-content-left" src="../../static/back.png" mode="widthFix"@click="handleClickBack" /><view class="nav-content-middle"><text>{{titleText}}</text></view></view><slot name="bottom" :style="'height:'+bottomComponentHeight +'px;'"></slot></view>
</template><script setup>import {onBeforeMount,ref,defineProps,defineEmits} from 'vue'const emits = defineEmits(['init-height'])/*** 整個導航欄的高度*/const navBarHeight = ref(0)/*** 狀態欄高度*/const navstatusBarHeight = ref(0)/*** 內容高度*/const navContentHeight = ref(0)/*** 距離右側膠囊的padding-right*/const navPaddingRight = ref(0)/*** 是否在tab頁*/const isInTab = getCurrentPages().length == 1/*** 獲取導航欄尺寸*/const initNavSize = () => {///獲取系統信息const {statusBarHeight,uniPlatform} = uni.getSystemInfoSync()///是否支持這個方法const isNoSupportGetMenuButton = (uniPlatform == "app") || (uniPlatform == "web") || (uniPlatform == "mp-lark")///內容高度let contentHeight = 0///計算內容高度if (!isNoSupportGetMenuButton) {///拿到膠囊信息const menuButton = uni.getMenuButtonBoundingClientRect()contentHeight = (menuButton.top - statusBarHeight) * 2 + menuButton.heightnavPaddingRight.value = menuButton.width + 24} else {contentHeight = 48navPaddingRight.value = 24}///賦值狀態欄高度navstatusBarHeight.value = statusBarHeight///賦值內容高度navContentHeight.value = contentHeight///總的高度=內容高度+狀態欄高度+bottom組件高度console.log("props.bottomComponentHeight is " + props.bottomComponentHeight)console.log("statusBarHeight is " + statusBarHeight)console.log("contentHeight is " + contentHeight)navBarHeight.value = statusBarHeight + contentHeight + parseInt(props.bottomComponentHeight)emits('init-height', navBarHeight.value)}/*** 返回*/const handleClickBack = () => {uni.navigateBack({delta: 1 // 返回的頁面數,這里設置為1表示返回上一頁});}const props =defineProps({///標題titleText: {type: String,default: ""},///是否使用自定義插槽isCustom: {type: Boolean,default: false},///bottom組件高度bottomComponentHeight: {type: String,default: "0"}})onBeforeMount(() => {initNavSize()})
</script><style lang="less">.nav-wrapper-container {height: var(--status-bar-height);width: 100%;position: fixed;width: 100%;top: 0;background-color: #f3f3f3;left: 0;z-index: 2;align-items: center;}.nav-status-container {width: 100%}.nav-content-container {width: 100%;display: flex;position: relative;align-items: center;}.nav-content-left {width: 40rpx;margin-left: 12rpx;}.nav-content-middle {position: absolute;left: 50%;transform: translate(-50%);}
</style>
使用方法:
使用默認配置:
<navbar titleText="這是標題"></navbar>
使用自定義插槽:
<navbar :isCustom="true" @init-height="initNavHeight" data-eventsync="true" bottomComponentHeight="45"><template v-slot:left><image class="nav-content-left" src="../../static/back.png" mode="widthFix" @click="handleClickBack" /></template><template v-slot:middle><view class="search-bar-middle" @click="handlerClickSearch()"><image src="../../static/search.png" mode="widthFix" style="width: 24rpx"></image><text class="search-bar-middle-text">搜索內容、體系、文章</text></view></template><template v-slot:bottom><classify-menu-bar :tabArr="tabArr" @on-change-tab="onChangeTab" class="classify-top-container"></classify-menu-bar></template></navbar>
一共有三個插槽:
- left: 左側
- middle:居中
- bottom:固定底部 (需用傳遞屬性,作為底部buttom的高度)