refactor: 将多主题功能从 pinia 抽离为 hook
This commit is contained in:
parent
e41d1f21a5
commit
281a7bebbf
@ -1,11 +1,11 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useAppStore } from "@/store/modules/app"
|
import { useTheme } from "@/hooks/useTheme"
|
||||||
import zhCn from "element-plus/lib/locale/lang/zh-cn"
|
import zhCn from "element-plus/lib/locale/lang/zh-cn"
|
||||||
|
|
||||||
const appStore = useAppStore()
|
const { initTheme } = useTheme()
|
||||||
|
|
||||||
/** 初始化主题 */
|
/** 初始化主题 */
|
||||||
appStore.initTheme()
|
initTheme()
|
||||||
/** 将 Element-Plus 的语言设置为中文 */
|
/** 将 Element-Plus 的语言设置为中文 */
|
||||||
const locale = zhCn
|
const locale = zhCn
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,17 +1,12 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed } from "vue"
|
import { useTheme } from "@/hooks/useTheme"
|
||||||
import { useAppStore } from "@/store/modules/app"
|
import type { ThemeName } from "@/hooks/useTheme"
|
||||||
import themeList from "@/config/theme"
|
|
||||||
import type { ThemeName } from "@/config/theme"
|
|
||||||
import { MagicStick } from "@element-plus/icons-vue"
|
import { MagicStick } from "@element-plus/icons-vue"
|
||||||
|
|
||||||
const appStore = useAppStore()
|
const { themeList, activeThemeName, setTheme } = useTheme()
|
||||||
|
|
||||||
const activeThemeName = computed(() => {
|
|
||||||
return appStore.activeThemeName
|
|
||||||
})
|
|
||||||
const handleSetTheme = (name: ThemeName) => {
|
const handleSetTheme = (name: ThemeName) => {
|
||||||
appStore.setTheme(name)
|
setTheme(name)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
/** 注册的主题, 其中 normal 是必须的, dark 是内置的, 如需更多主题,可自行注册 */
|
|
||||||
export type ThemeName = "normal" | "dark"
|
|
||||||
|
|
||||||
interface IThemeList {
|
|
||||||
title: string
|
|
||||||
name: ThemeName
|
|
||||||
}
|
|
||||||
|
|
||||||
const themeList: IThemeList[] = [
|
|
||||||
{
|
|
||||||
title: "默认",
|
|
||||||
name: "normal"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "黑暗",
|
|
||||||
name: "dark"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
export default themeList
|
|
44
src/hooks/useTheme.ts
Normal file
44
src/hooks/useTheme.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import { ref } from "vue"
|
||||||
|
import { getActiveThemeName, setActiveThemeName } from "@/utils/cache/localStorage"
|
||||||
|
|
||||||
|
interface IThemeList {
|
||||||
|
title: string
|
||||||
|
name: ThemeName
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 注册的主题名称, 其中 normal 是必填的 */
|
||||||
|
export type ThemeName = "normal" | "dark"
|
||||||
|
|
||||||
|
/** 主题 hook */
|
||||||
|
export function useTheme() {
|
||||||
|
/** 主题列表 */
|
||||||
|
const themeList: IThemeList[] = [
|
||||||
|
{
|
||||||
|
title: "默认",
|
||||||
|
name: "normal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "黑暗",
|
||||||
|
name: "dark"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
/** 正在应用的主题名称 */
|
||||||
|
const activeThemeName = ref<ThemeName>(getActiveThemeName() || "normal")
|
||||||
|
|
||||||
|
const initTheme = () => {
|
||||||
|
setHtmlClassName(activeThemeName.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const setTheme = (value: ThemeName) => {
|
||||||
|
activeThemeName.value = value
|
||||||
|
setHtmlClassName(activeThemeName.value)
|
||||||
|
setActiveThemeName(activeThemeName.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 在 html 根元素上挂载 class */
|
||||||
|
const setHtmlClassName = (value: ThemeName) => {
|
||||||
|
document.documentElement.className = value
|
||||||
|
}
|
||||||
|
|
||||||
|
return { themeList, activeThemeName, initTheme, setTheme }
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
import { reactive, ref } from "vue"
|
import { reactive, ref } from "vue"
|
||||||
import { defineStore } from "pinia"
|
import { defineStore } from "pinia"
|
||||||
import { getSidebarStatus, getActiveThemeName, setSidebarStatus, setActiveThemeName } from "@/utils/cache/localStorage"
|
import { getSidebarStatus, setSidebarStatus } from "@/utils/cache/localStorage"
|
||||||
import type { ThemeName } from "@/config/theme"
|
|
||||||
|
|
||||||
export enum DeviceType {
|
export enum DeviceType {
|
||||||
Mobile,
|
Mobile,
|
||||||
@ -13,18 +12,12 @@ interface ISidebar {
|
|||||||
withoutAnimation: boolean
|
withoutAnimation: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const setClassName = (value: ThemeName) => {
|
|
||||||
document.documentElement.className = value
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useAppStore = defineStore("app", () => {
|
export const useAppStore = defineStore("app", () => {
|
||||||
const sidebar: ISidebar = reactive({
|
const sidebar: ISidebar = reactive({
|
||||||
opened: getSidebarStatus() !== "closed",
|
opened: getSidebarStatus() !== "closed",
|
||||||
withoutAnimation: false
|
withoutAnimation: false
|
||||||
})
|
})
|
||||||
const device = ref<DeviceType>(DeviceType.Desktop)
|
const device = ref<DeviceType>(DeviceType.Desktop)
|
||||||
/** 正在应用的主题的名字 */
|
|
||||||
const activeThemeName = ref<ThemeName>(getActiveThemeName() || "normal")
|
|
||||||
|
|
||||||
const toggleSidebar = (withoutAnimation: boolean) => {
|
const toggleSidebar = (withoutAnimation: boolean) => {
|
||||||
sidebar.opened = !sidebar.opened
|
sidebar.opened = !sidebar.opened
|
||||||
@ -43,17 +36,6 @@ export const useAppStore = defineStore("app", () => {
|
|||||||
const toggleDevice = (value: DeviceType) => {
|
const toggleDevice = (value: DeviceType) => {
|
||||||
device.value = value
|
device.value = value
|
||||||
}
|
}
|
||||||
const setTheme = (value: ThemeName) => {
|
|
||||||
activeThemeName.value = value
|
|
||||||
// 应用到 Dom
|
|
||||||
setClassName(activeThemeName.value)
|
|
||||||
// 持久化
|
|
||||||
setActiveThemeName(activeThemeName.value)
|
|
||||||
}
|
|
||||||
const initTheme = () => {
|
|
||||||
// 初始化
|
|
||||||
setClassName(activeThemeName.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
return { device, sidebar, activeThemeName, toggleSidebar, closeSidebar, toggleDevice, setTheme, initTheme }
|
return { device, sidebar, toggleSidebar, closeSidebar, toggleDevice }
|
||||||
})
|
})
|
||||||
|
2
src/utils/cache/localStorage.ts
vendored
2
src/utils/cache/localStorage.ts
vendored
@ -1,7 +1,7 @@
|
|||||||
/** 统一处理 localStorage */
|
/** 统一处理 localStorage */
|
||||||
|
|
||||||
import CacheKey from "@/constants/cacheKey"
|
import CacheKey from "@/constants/cacheKey"
|
||||||
import type { ThemeName } from "@/config/theme"
|
import type { ThemeName } from "@/hooks/useTheme"
|
||||||
|
|
||||||
export const getSidebarStatus = () => {
|
export const getSidebarStatus = () => {
|
||||||
return localStorage.getItem(CacheKey.SIDEBAR_STATUS)
|
return localStorage.getItem(CacheKey.SIDEBAR_STATUS)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user