import { ref, computed, watch } from "vue"; import { defineStore } from "pinia"; // 本地存储主题的键名 const THEME_STORAGE_KEY = "fpga-weblab-theme"; export const useThemeStore = defineStore("theme", () => { const allTheme = ["winter", "night"]; const darkTheme = "night"; const lightTheme = "winter"; // 尝试从本地存储中获取保存的主题 const getSavedTheme = (): string | null => { return localStorage.getItem(THEME_STORAGE_KEY); }; // 检测系统主题偏好 const getPreferredTheme = (): string => { const savedTheme = getSavedTheme(); // 如果有保存的主题设置,优先使用 if (savedTheme && allTheme.includes(savedTheme)) { return savedTheme; } // 否则检测系统主题模式 return window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches ? darkTheme : lightTheme; }; // 初始化主题为首选主题 const currentTheme = ref(getPreferredTheme()); const currentMode = computed(() => currentTheme.value === darkTheme ? "dark" : "light", ); // 保存主题到本地存储 const saveTheme = (theme: string) => { localStorage.setItem(THEME_STORAGE_KEY, theme); }; // 当主题变化时,保存到本地存储 watch(currentTheme, (newTheme) => { saveTheme(newTheme); }); // 添加系统主题变化的监听 const setupThemeListener = () => { if (window.matchMedia) { const colorSchemeQuery = window.matchMedia( "(prefers-color-scheme: dark)", ); const handler = (e: MediaQueryListEvent) => { // 只有当用户没有手动设置过主题时,才跟随系统变化 if (!getSavedTheme()) { currentTheme.value = e.matches ? darkTheme : lightTheme; } }; // 添加主题变化监听器 colorSchemeQuery.addEventListener("change", handler); } }; function setTheme(theme: string) { const isContained: boolean = allTheme.includes(theme); if (isContained) { currentTheme.value = theme; saveTheme(theme); // 保存主题到本地存储 } else { console.error(`Not have such theme: ${theme}`); } } function toggleTheme() { if (currentTheme.value == darkTheme) { currentTheme.value = lightTheme; } else if (currentTheme.value == lightTheme) { currentTheme.value = darkTheme; } else { currentTheme.value = lightTheme; } // 主题切换时自动保存(通过 watch 函数实现) } function isDarkTheme(): boolean { return currentTheme.value == darkTheme; } function isLightTheme(): boolean { return currentTheme.value == lightTheme; } // 初始化时设置系统主题变化监听器 if (typeof window !== "undefined") { setupThemeListener(); } return { allTheme, currentTheme, currentMode, setTheme, toggleTheme, isDarkTheme, isLightTheme, setupThemeListener, }; });