65 lines
1.5 KiB
TypeScript
Raw Normal View History

import { getActiveThemeName, setActiveThemeName } from "@@/utils/cache/local-storage"
2023-02-28 14:12:38 +08:00
const DEFAULT_THEME_NAME = "normal"
type DefaultThemeName = typeof DEFAULT_THEME_NAME
2023-02-28 14:12:38 +08:00
/** 注册的主题名称, 其中 DefaultThemeName 是必填的 */
export type ThemeName = DefaultThemeName | "dark" | "dark-blue"
2023-02-28 14:12:38 +08:00
interface ThemeList {
title: string
name: ThemeName
}
2022-10-21 11:25:06 +08:00
/** 主题列表 */
const themeList: ThemeList[] = [
2022-10-21 11:25:06 +08:00
{
title: "默认",
2023-02-28 14:12:38 +08:00
name: DEFAULT_THEME_NAME
2022-10-21 11:25:06 +08:00
},
{
title: "黑暗",
name: "dark"
2022-10-21 18:06:56 +08:00
},
{
title: "深蓝",
name: "dark-blue"
}
2022-10-21 11:25:06 +08:00
]
2022-10-21 11:25:06 +08:00
/** 正在应用的主题名称 */
2023-02-28 14:12:38 +08:00
const activeThemeName = ref<ThemeName>(getActiveThemeName() || DEFAULT_THEME_NAME)
2023-05-19 21:02:20 +08:00
/** 设置主题 */
2024-11-18 19:40:44 +08:00
function setTheme(value: ThemeName) {
2022-10-21 11:25:06 +08:00
activeThemeName.value = value
}
/** 在 html 根元素上挂载 class */
2024-11-18 19:40:44 +08:00
function addHtmlClass(value: ThemeName) {
document.documentElement.classList.add(value)
}
/** 在 html 根元素上移除其他主题 class */
2024-11-18 19:40:44 +08:00
function removeHtmlClass(value: ThemeName) {
const otherThemeNameList = themeList.map(item => item.name).filter(name => name !== value)
document.documentElement.classList.remove(...otherThemeNameList)
2022-10-21 11:25:06 +08:00
}
2023-05-19 21:02:20 +08:00
/** 初始化 */
2024-11-18 19:40:44 +08:00
function initTheme() {
2023-05-19 21:02:20 +08:00
// watchEffect 来收集副作用
watchEffect(() => {
const value = activeThemeName.value
removeHtmlClass(value)
addHtmlClass(value)
setActiveThemeName(value)
})
}
/** 主题 Composable */
2022-10-21 11:25:06 +08:00
export function useTheme() {
return { themeList, activeThemeName, initTheme, setTheme }
}