anon-ui/src/components/tabbar/CustomOwnBar.vue
2025-03-10 09:20:36 +08:00

176 lines
3.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view>
<!-- 顶部导航栏 -->
<uni-nav-bar
:title="titles"
:status-bar="true"
fixed
left-icon="back"
:border="false"
background-color="#FFFFFF"
color="#000000"
/>
<!-- 导航栏占位,确保内容不被覆盖 -->
<view class="nav-placeholder"></view>
<div class="slot-wrapper">
<slot></slot>
</div>
<tui-tabbar :current="current" backdropFilter backgroundColor="#f8f8f8" :tabBar="tabbar" color="#777" selectedColor="#AC9157" @click="tabbarSwitch"></tui-tabbar>
</view>
</template>
<script setup lang="ts">
import TuiTabbar from "@/components/thorui/tui-tabbar/tui-tabbar.vue";
import {tabbarState} from "@/store/tabbar";
import UniNavBar from "@/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-nav-bar.vue";
interface TabbarItem {
pagePath: string;
text: string;
iconPath: string;
selectedIconPath: string;
verify?: boolean;
}
const tabbar = ref<TabbarItem[]>([
{
pagePath: '/pages/index/index',
text: '写信',
iconPath: '/static/images/send.png',
selectedIconPath: '/static/images/send-active.png'
},
{
pagePath: '/pages/mailbox/index',
text: '信箱',
iconPath: '/static/images/mailbox.png',
selectedIconPath: '/static/images/mailbox-active.png'
},
{
pagePath: '/pages/mine/index',
text: '我的',
iconPath: '/static/images/mine.png',
selectedIconPath: '/static/images/mine-active.png',
verify: true,
}
]);
// 定义初始化页面的页数
const current = computed(() => tabbarState.currentTab.value);
//定义当前顶部导航的Title文案
const titles = ref<string>("");
const navBarHeight = ref(64); // 默认值 64px
const getTitle = () => {
let title = "";
switch (tabbarState.currentTab.value) {
case 0:
title = "首页";
break;
case 1:
title = "信箱";
break;
case 2:
title = "我的";
break;
default:
title = "";
}
titles.value = title;
};
onMounted(() => {
// 获取导航文案
getTitle();
// 计算导航栏高度
calcNavBarHeight();
});
// 点击切换页面的事件
const tabbarSwitch = (e: any) => {
const index = typeof e === 'number' ? e : e.index;
// 如果点击当前已选中的标签,不执行任何操作
if (index === current.value) return;
console.log("触发切换页面:", index);
//获取登录状态,此处默认未登录
//跳转切换逻辑需自行实现
let isLogin = false;
if (e.verify && !isLogin) {
console.log("需要登陆才可以访问")
}else{
tabbarState.setCurrentTab(index);
// 预加载页面,然后再切换
Promise.resolve().then(() => {
uni.switchTab({
url: tabbar.value[index].pagePath
});
});
}
};
const calcNavBarHeight = () => {
try {
const sysInfo = uni.getSystemInfoSync();
const statusBarHeight = sysInfo.statusBarHeight || 20;
const navContentHeight = 44; // 导航栏内容高度通常是44px
navBarHeight.value = statusBarHeight + navContentHeight;
// 设置CSS变量以供样式使用
document.documentElement.style.setProperty('--nav-bar-height', `${navBarHeight.value}px`);
} catch (e) {
// 故障保护
navBarHeight.value = 64;
document.documentElement.style.setProperty('--nav-bar-height', `64px`);
}
};
</script>
<style>
/* 根级别CSS变量 */
:root {
--nav-bar-height: 124px; /* 默认值,会被JS动态更新 */
}
/* 导航栏占位,确保内容不被导航栏覆盖 */
.nav-placeholder {
width: 100%;
height: var(--nav-bar-height);
flex-shrink: 0;
}
.slot-wrapper{
flex: 1;
width: 100%;
box-sizing: border-box;
/* 内容区域到底部tabbar的距离 */
padding-bottom: 50px;
position: relative;
/* 消除所有可能的边距 */
margin: 0;
padding-top: 0;
}
/* 确保页面级别设置正确 */
page {
margin: 0;
padding: 0;
background-color: #ffffff;
box-sizing: border-box;
}
</style>