feat(router): 添加页面标题和滚动重置功能

- 为路由添加 meta.title 配置,在导航守卫中动态设置文档标题
- 添加 afterEach 钩子,在路由切换时重置布局内容和窗口滚动位置
- 标准化路由配置的逗号格式,增强代码一致性
- 优化主题切换 composable 的代码格式和注释翻译
- 改进访问统计页面的排序逻辑,使用 computed 替代手动重新加载
- 添加全局滚动条样式,提升视觉一致性
This commit is contained in:
anghunk
2026-01-29 17:16:11 +08:00
parent cfeedc36bb
commit 29f29f8b77
4 changed files with 157 additions and 93 deletions

View File

@@ -6,52 +6,49 @@ const STORAGE_KEY = 'cwd_admin_theme';
const theme = ref<Theme>('system');
export function useTheme() {
function applyTheme() {
if (typeof window === 'undefined') return;
const root = document.documentElement;
const isDark =
theme.value === 'dark' ||
(theme.value === 'system' &&
window.matchMedia('(prefers-color-scheme: dark)').matches);
function applyTheme() {
if (typeof window === 'undefined') return;
if (isDark) {
root.classList.add('dark');
} else {
root.classList.remove('dark');
}
}
const root = document.documentElement;
const isDark = theme.value === 'dark' || (theme.value === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches);
function setTheme(newTheme: Theme) {
theme.value = newTheme;
localStorage.setItem(STORAGE_KEY, newTheme);
applyTheme();
}
if (isDark) {
root.classList.add('dark');
} else {
root.classList.remove('dark');
}
}
function initTheme() {
if (typeof window === 'undefined') return;
function setTheme(newTheme: Theme) {
theme.value = newTheme;
localStorage.setItem(STORAGE_KEY, newTheme);
applyTheme();
}
const stored = localStorage.getItem(STORAGE_KEY) as Theme | null;
if (stored && ['light', 'dark', 'system'].includes(stored)) {
theme.value = stored;
} else {
theme.value = 'system';
}
applyTheme();
function initTheme() {
if (typeof window === 'undefined') return;
// Listen for system changes
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
// Remove existing listener to avoid duplicates if init is called multiple times (though it shouldn't be)
mediaQuery.onchange = () => {
if (theme.value === 'system') {
applyTheme();
}
};
}
const stored = localStorage.getItem(STORAGE_KEY) as Theme | null;
if (stored && ['light', 'dark', 'system'].includes(stored)) {
theme.value = stored;
} else {
theme.value = 'system';
}
applyTheme();
return {
theme,
setTheme,
initTheme
};
// 监听系统变更
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
// 移除现有的监听器,以避免 init 被多次调用时出现重复监听(尽管不应该重复监听)。
mediaQuery.onchange = () => {
if (theme.value === 'system') {
applyTheme();
}
};
}
return {
theme,
setTheme,
initTheme,
};
}