176 lines
3.9 KiB
Vue
176 lines
3.9 KiB
Vue
<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> |