Files
EmailBill/Web/src/App.vue
孙诚 3ca9ceb6fb
All checks were successful
Docker Build & Deploy / Build Docker Image (push) Successful in 12s
Docker Build & Deploy / Deploy to Production (push) Successful in 6s
移除调试信息
2025-12-25 17:30:29 +08:00

122 lines
3.0 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>
<van-config-provider :theme="theme" class="app-provider">
<div class="app-root">
<RouterView />
<van-tabbar v-model="active" v-show="showTabbar">
<van-tabbar-item icon="notes-o" to="/calendar">
日历
</van-tabbar-item>
<van-tabbar-item icon="balance-list-o" to="/" @click="handleTabClick('/')">
账单
</van-tabbar-item>
<van-tabbar-item icon="records-o" to="/email" @click="handleTabClick('/email')">
邮件
</van-tabbar-item>
<van-tabbar-item icon="setting-o" to="/setting">
设置
</van-tabbar-item>
</van-tabbar>
</div>
</van-config-provider>
</template>
<script setup>
import { RouterView, useRoute } from 'vue-router'
import { ref, onMounted, onUnmounted, computed } from 'vue'
const updateVh = () => {
// 获取真实的视口高度PWA 模式下准确)
const vh = window.innerHeight
// 设置 CSS 变量,让所有组件使用准确的视口高度
document.documentElement.style.setProperty('--vh', `${vh}px`)
}
onMounted(() => {
updateVh()
window.addEventListener('resize', updateVh)
// 监听 iOS Safari 视口变化
if (window.visualViewport) {
window.visualViewport.addEventListener('resize', updateVh)
}
})
onUnmounted(() => {
window.removeEventListener('resize', updateVh)
if (window.visualViewport) {
window.visualViewport.removeEventListener('resize', updateVh)
}
})
const route = useRoute()
// 根据路由判断是否显示Tabbar
const showTabbar = computed(() => {
return route.path === '/' ||
route.path === '/calendar' ||
route.path === '/email' ||
route.path === '/setting'
})
const active = ref(0)
const theme = ref('light')
// 检测系统深色模式
const updateTheme = () => {
const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches
theme.value = isDark ? 'dark' : 'light'
}
// 监听系统主题变化
let mediaQuery
onMounted(() => {
updateTheme()
mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
mediaQuery.addEventListener('change', updateTheme)
})
onUnmounted(() => {
if (mediaQuery) {
mediaQuery.removeEventListener('change', updateTheme)
}
})
// 处理tab点击如果点击当前页面则滚动到顶部
const handleTabClick = (path) => {
if (route.path === path) {
window.scrollTo({ top: 0, behavior: 'smooth' })
}
}
</script>
<style scoped>
.app-provider {
/* 使用准确的视口高度 CSS 变量 */
height: var(--vh, 100vh);
width: 100%;
}
.app-root {
height: 100%;
width: 100%;
position: relative;
}
/* TabBar 固定在底部 */
:deep(.van-tabbar) {
position: fixed !important;
bottom: 0 !important;
left: 0;
right: 0;
/* 重置所有 padding然后只添加安全区域 */
padding: 0 !important;
padding-bottom: env(safe-area-inset-bottom, 0px) !important;
height: 50px !important;
min-height: 50px !important;
}
/* 确保 TabBar 项目居中 */
:deep(.van-tabbar-item) {
padding: 0 !important;
}
</style>