feat(store): 重构应用状态管理,移除旧的 app-store 并引入 app-store-auto-imports
Some checks failed
CI/CD Pipeline / playwright (push) Successful in 4m10s
CI/CD Pipeline / build-and-deploy (push) Successful in 4m33s
测试最新依赖 / playwright (push) Successful in 2m16s
测试最新依赖 / build-and-test (push) Failing after 2m26s

This commit is contained in:
严浩
2025-10-29 23:37:31 +08:00
parent 2874fdfaa7
commit f81c7614be
9 changed files with 64 additions and 78 deletions

View File

@@ -0,0 +1,42 @@
import { useLocalStorage, useMediaQuery } from '@vueuse/core';
import { defineStore } from 'pinia';
import { computed } from 'vue';
// >>>>>
// https://vueuse.org/core/useColorMode/#advanced-usage
const { system, store: themeMode } = useColorMode({
modes: { light: '', dark: 'app-dark', auto: '' },
disableTransition: false,
});
const { state, next: cycleTheme } = useCycleList(['light', 'dark', 'auto'] as const, {
initialValue: themeMode,
});
watchEffect(() => (themeMode.value = state.value));
export type AppThemeMode = typeof themeMode.value;
// <<<<<
export const useAppStore = defineStore('app', () => {
// 侧边栏展开/收起状态
const sidebarCollapsed = useLocalStorage<boolean>('app-sidebar-collapsed', false);
const toggleSidebar = useToggle(sidebarCollapsed);
// 主题模式
const actualTheme = computed(() => (themeMode.value === 'auto' ? system.value : themeMode.value));
const isDark = computed(() => actualTheme.value === 'dark');
// 是否是移动端
const isMobile = useMediaQuery('(max-width: 768px)');
return {
themeMode,
isDark,
isMobile,
cycleTheme,
sidebarCollapsed,
toggleSidebar,
};
});
if (import.meta.hot) {
import.meta.hot.accept(acceptHMRUpdate(useAppStore, import.meta.hot));
}

View File

@@ -1,64 +0,0 @@
import { useLocalStorage, useMediaQuery, usePreferredColorScheme } from '@vueuse/core';
import { defineStore } from 'pinia';
import { computed, watch } from 'vue';
export const APP_THEME_MODES = ['light', 'dark', 'system'] as const;
export type AppThemeMode = (typeof APP_THEME_MODES)[number];
const DARK_CLASS = 'app-dark';
export const useAppStore = defineStore('app', () => {
const themeMode = useLocalStorage<AppThemeMode>('app-theme-mode', 'system');
const preferredColor = usePreferredColorScheme();
// 侧边栏展开/收起状态
const sidebarCollapsed = useLocalStorage<boolean>('app-sidebar-collapsed', false);
// 计算实际使用的主题
const actualTheme = computed(() =>
themeMode.value === 'system'
? preferredColor.value === 'dark'
? 'dark'
: 'light'
: themeMode.value,
);
// 是否是暗色主题
const isDark = computed(() => actualTheme.value === 'dark');
// 是否是移动端
const isMobile = useMediaQuery('(max-width: 768px)');
// 更新 DOM 类名
function updateDomClass() {
document.documentElement.classList.toggle(DARK_CLASS, isDark.value);
}
// 循环切换主题
function cycleTheme() {
const currentIndex = APP_THEME_MODES.indexOf(themeMode.value);
const nextIndex = (currentIndex + 1) % APP_THEME_MODES.length;
themeMode.value = APP_THEME_MODES[nextIndex]!;
}
// 切换侧边栏展开/收起
function toggleSidebar() {
sidebarCollapsed.value = !sidebarCollapsed.value;
}
// 监听主题变化,更新 DOM
watch(isDark, updateDomClass, { immediate: true });
return {
themeMode,
isDark,
isMobile,
cycleTheme,
sidebarCollapsed,
toggleSidebar,
};
});
if (import.meta.hot) {
import.meta.hot.accept(acceptHMRUpdate(useAppStore, import.meta.hot));
}