2026-01-31 22:37:24 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<view>
|
|
|
|
|
|
<!-- Placeholder to occupy space if fixed -->
|
|
|
|
|
|
<view
|
2026-01-31 23:44:00 +08:00
|
|
|
|
v-if="fixed && placeholder && !transparent"
|
2026-01-31 22:37:24 +08:00
|
|
|
|
class="nav-placeholder"
|
|
|
|
|
|
:style="{ height: navBarHeight + 'px' }"
|
|
|
|
|
|
></view>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Actual Navbar -->
|
|
|
|
|
|
<view
|
|
|
|
|
|
class="nav-bar"
|
|
|
|
|
|
:class="{ fixed: fixed }"
|
|
|
|
|
|
:style="{
|
|
|
|
|
|
height: navBarHeight + 'px',
|
|
|
|
|
|
paddingTop: statusBarHeight + 'px',
|
2026-01-31 23:44:00 +08:00
|
|
|
|
backgroundColor: transparent ? 'transparent' : background,
|
2026-01-31 22:37:24 +08:00
|
|
|
|
color: color
|
|
|
|
|
|
}"
|
|
|
|
|
|
>
|
|
|
|
|
|
<view class="nav-content">
|
|
|
|
|
|
<view
|
|
|
|
|
|
v-if="back"
|
|
|
|
|
|
class="back"
|
|
|
|
|
|
@tap="goBack"
|
|
|
|
|
|
:style="{ color: color }"
|
|
|
|
|
|
>‹</view>
|
|
|
|
|
|
<text class="nav-title" :style="{ color: color }">{{ title }}</text>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
|
|
import { ref, onMounted } from "vue";
|
|
|
|
|
|
import { getBavBarHeight, getStatusBarHeight } from "@/utils/system";
|
|
|
|
|
|
|
|
|
|
|
|
const props = defineProps({
|
|
|
|
|
|
title: {
|
|
|
|
|
|
type: String,
|
|
|
|
|
|
default: "",
|
|
|
|
|
|
},
|
|
|
|
|
|
background: {
|
|
|
|
|
|
type: String,
|
|
|
|
|
|
default: "#ffffff",
|
|
|
|
|
|
},
|
|
|
|
|
|
color: {
|
|
|
|
|
|
type: String,
|
|
|
|
|
|
default: "#333333",
|
|
|
|
|
|
},
|
|
|
|
|
|
back: {
|
|
|
|
|
|
type: Boolean,
|
|
|
|
|
|
default: true,
|
|
|
|
|
|
},
|
|
|
|
|
|
fixed: {
|
|
|
|
|
|
type: Boolean,
|
|
|
|
|
|
default: true,
|
|
|
|
|
|
},
|
|
|
|
|
|
placeholder: {
|
|
|
|
|
|
type: Boolean,
|
|
|
|
|
|
default: true,
|
|
|
|
|
|
},
|
2026-01-31 23:44:00 +08:00
|
|
|
|
transparent: {
|
|
|
|
|
|
type: Boolean,
|
|
|
|
|
|
default: false,
|
|
|
|
|
|
},
|
2026-01-31 22:37:24 +08:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const navBarHeight = ref(64);
|
|
|
|
|
|
const statusBarHeight = ref(20);
|
|
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
|
navBarHeight.value = getBavBarHeight();
|
|
|
|
|
|
statusBarHeight.value = getStatusBarHeight();
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const goBack = () => {
|
|
|
|
|
|
const pages = getCurrentPages();
|
|
|
|
|
|
if (pages.length > 1) {
|
|
|
|
|
|
uni.navigateBack();
|
|
|
|
|
|
} else {
|
|
|
|
|
|
uni.switchTab({ url: "/pages/index/index" });
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
|
.nav-bar {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
z-index: 999;
|
|
|
|
|
|
|
|
|
|
|
|
&.fixed {
|
|
|
|
|
|
position: fixed;
|
|
|
|
|
|
top: 0;
|
|
|
|
|
|
left: 0;
|
|
|
|
|
|
right: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.nav-content {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
height: 100%;
|
|
|
|
|
|
padding: 0 24rpx;
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.back {
|
|
|
|
|
|
font-size: 50rpx;
|
|
|
|
|
|
margin-right: 24rpx;
|
|
|
|
|
|
line-height: 1;
|
|
|
|
|
|
padding: 20rpx;
|
|
|
|
|
|
margin-left: -20rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.nav-title {
|
|
|
|
|
|
font-size: 34rpx;
|
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
margin-right: 50rpx; /* Balance back button */
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|