Files
youlai-app/src/store/modules/theme.ts
Ray.Hao 4465c4d613 feat: 全面升级 Wot UI v2 并修复暗黑模式适配
- 修复 TabBar 切换激活状态不同步问题
- 修复大量 Wot UI 2.x 图标名称不匹配
- 修复暗黑模式下主题变量错误注入导致亮色模式显示异常
- 优化个人中心 UI(头像标记、图标背景色、菜单结构)
- 重构首页图表时间选择器为自定义分段选择器
- 修复登录弹窗文字丢失及验证顺序
- 修复设置页面布局、退出登录按钮及 cell 点击态
2026-05-17 23:54:28 +08:00

175 lines
4.7 KiB
TypeScript

import { defineStore } from "pinia";
import { Storage } from "@/utils/storage";
import { THEME_MODE_KEY, THEME_COLOR_KEY } from "@/constants";
import type { ThemeColorOption, ThemeMode } from "@/composables/types/theme";
import { themeColorOptions } from "@/composables/types/theme";
/**
* 主题状态管理 Store
*
* 功能说明:
* - 主题模式切换(明/暗)
* - 主题色定制
* - 导航栏颜色同步
*/
export const useThemeStore = defineStore("theme", () => {
// ==========================================================================
// 状态
// ==========================================================================
/** 当前主题模式 */
const theme = ref<ThemeMode>(Storage.get<ThemeMode>(THEME_MODE_KEY, "light"));
/** 当前主题色 */
const currentThemeColor = ref<ThemeColorOption>(
Storage.get<ThemeColorOption>(THEME_COLOR_KEY, themeColorOptions[0])
);
/**
* 深色主题变量(仅在 dark 模式下注入)
*/
const darkThemeVars = {
darkBackground: "#1f2937",
darkBackground2: "#111827",
darkBackground3: "#1e293b",
darkBackground4: "#374151",
darkBackground5: "#4b5563",
darkBackground6: "#6b7280",
darkBackground7: "#9ca3af",
darkColor: "#f9fafb",
darkColor2: "#9ca3af",
darkColor3: "#6b7280",
filledOppo: "#1f2937",
cardBg: "#1f2937",
cardBorderColor: "#374151",
cardTitleColor: "#f9fafb",
cardContentColor: "#9ca3af",
gridItemBg: "#1f2937",
gridItemTextColor: "#f9fafb",
gridItemIconColor: "#9ca3af",
cellBg: "#1f2937",
popupBg: "#1f2937",
searchBg: "#1f2937",
searchInputBg: "#374151",
inputBg: "#374151",
textareaBg: "#374151",
pickerBg: "#1f2937",
dialogBg: "#1f2937",
actionSheetBg: "#1f2937",
tabsNavBg: "#1f2937",
tabbarBg: "#1f2937",
navbarBg: "#1f2937",
buttonNormalBg: "#374151",
borderMain: "#374151",
borderLight: "#4b5563",
textMain: "#f9fafb",
textSecondary: "#9ca3af",
textPlaceholder: "#6b7280",
iconMain: "#f9fafb",
iconSecondary: "#9ca3af",
baseBlack: "#1f2937",
baseWhite: "#f9fafb",
};
/** 主题变量(计算属性,根据模式动态切换) */
const themeVars = computed(() => {
const base = { colorTheme: currentThemeColor.value.primary };
if (theme.value === "dark") {
return { ...base, ...darkThemeVars };
}
return base;
});
// ==========================================================================
// 计算属性
// ==========================================================================
/** 是否为暗黑模式 */
const isDark = computed(() => theme.value === "dark");
/**
* 将 themeVars 转换为 CSS 变量内联样式字符串
* light 模式下只注入主题色,避免覆盖 Wot UI 默认亮色样式
* dark 模式下注入完整的深色变量覆盖
*/
const kebabCase = (str: string) =>
str
.replace(/^./, (s) => s.toLowerCase())
.replace(/([a-z])([A-Z])/g, "$1-$2")
.replace(/(\d)/g, "-$1")
.toLowerCase();
const themeCSSVars = computed(() => {
if (theme.value === "light") {
return `--wot-color-theme:${themeVars.value.colorTheme};`;
}
return Object.entries(themeVars.value)
.map(([key, val]) => `--wot-${kebabCase(key)}:${val}`)
.join(";");
});
// ==========================================================================
// 方法
// ==========================================================================
/**
* 设置导航栏颜色
*/
const setNavigationBarColor = () => {
uni.setNavigationBarColor({
frontColor: theme.value === "light" ? "#000000" : "#ffffff",
backgroundColor: theme.value === "light" ? "#ffffff" : "#1f2937",
});
};
/**
* 切换主题
* @param mode 指定主题模式,不传则自动切换
*/
const toggleTheme = (mode?: ThemeMode) => {
theme.value = mode || (theme.value === "light" ? "dark" : "light");
Storage.set(THEME_MODE_KEY, theme.value);
setNavigationBarColor();
};
/**
* 设置主题色
* @param color 主题色选项
*/
const setCurrentThemeColor = (color: ThemeColorOption) => {
currentThemeColor.value = color;
Storage.set(THEME_COLOR_KEY, color);
};
/**
* 初始化主题
*/
const initTheme = () => {
nextTick(() => {
setNavigationBarColor();
});
};
// ==========================================================================
// 导出
// ==========================================================================
return {
// 状态
theme,
currentThemeColor,
themeVars,
// 计算属性
isDark,
themeCSSVars,
// 方法
toggleTheme,
setCurrentThemeColor,
setNavigationBarColor,
initTheme,
};
});