118 lines
2.3 KiB
Vue
118 lines
2.3 KiB
Vue
<script setup lang="ts">
|
||
import Navbar from "./components/Navbar.vue";
|
||
import Dialog from "./components/Dialog.vue";
|
||
import { Alert, useAlertProvider } from "./components/Alert";
|
||
import { ref, provide, computed, onMounted } from "vue";
|
||
import { useRouter } from "vue-router";
|
||
|
||
const router = useRouter();
|
||
|
||
// 主题切换状态管理
|
||
const isDarkMode = ref(
|
||
window.matchMedia("(prefers-color-scheme: dark)").matches,
|
||
);
|
||
|
||
// Navbar显示状态管理
|
||
const showNavbar = ref(true);
|
||
|
||
// 切换Navbar显示状态
|
||
const toggleNavbar = () => {
|
||
showNavbar.value = !showNavbar.value;
|
||
};
|
||
|
||
// 初始化主题设置
|
||
onMounted(() => {
|
||
// 应用初始主题
|
||
applyTheme();
|
||
|
||
// 监听系统主题变化
|
||
window
|
||
.matchMedia("(prefers-color-scheme: dark)")
|
||
.addEventListener("change", (e) => {
|
||
// 跟随系统变化
|
||
isDarkMode.value = e.matches;
|
||
applyTheme();
|
||
});
|
||
});
|
||
|
||
// 应用主题到文档
|
||
const applyTheme = () => {
|
||
document.documentElement.setAttribute(
|
||
"data-theme",
|
||
isDarkMode.value ? "night" : "winter",
|
||
);
|
||
};
|
||
|
||
// 切换主题
|
||
const toggleTheme = () => {
|
||
isDarkMode.value = !isDarkMode.value;
|
||
applyTheme();
|
||
};
|
||
|
||
// 提供主题状态和切换方法给子组件
|
||
provide("theme", {
|
||
isDarkMode,
|
||
toggleTheme,
|
||
});
|
||
|
||
// 提供Navbar控制给子组件
|
||
provide("navbar", {
|
||
showNavbar,
|
||
toggleNavbar,
|
||
});
|
||
|
||
const currentRoutePath = computed(() => {
|
||
return router.currentRoute.value.path;
|
||
});
|
||
|
||
useAlertProvider();
|
||
</script>
|
||
|
||
<template>
|
||
<div>
|
||
<header class="relative" :class="{ 'navbar-hidden': !showNavbar }">
|
||
<Navbar v-show="showNavbar" />
|
||
<Dialog />
|
||
<Alert />
|
||
</header>
|
||
|
||
<main>
|
||
<RouterView />
|
||
</main>
|
||
|
||
<footer
|
||
v-if="currentRoutePath != '/project'"
|
||
class="footer footer-center p-4 bg-base-300 text-base-content"
|
||
>
|
||
<div>
|
||
<p>Copyright © 2023 - All right reserved by OurEDA</p>
|
||
</div>
|
||
</footer>
|
||
</div>
|
||
</template>
|
||
|
||
<style scoped>
|
||
/* 特定于App.vue的样式 */
|
||
header {
|
||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||
transform-origin: top;
|
||
}
|
||
|
||
.navbar-hidden {
|
||
transform: scaleY(0);
|
||
height: 0;
|
||
overflow: hidden;
|
||
}
|
||
|
||
/* Navbar显示/隐藏动画 */
|
||
header .navbar {
|
||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||
transform-origin: top;
|
||
}
|
||
|
||
/* 当header被隐藏时,确保navbar也相应变化 */
|
||
.navbar-hidden .navbar {
|
||
opacity: 0;
|
||
}
|
||
</style>
|