mirror of
https://github.com/un-pany/v3-admin-vite.git
synced 2025-04-21 11:29:20 +08:00
refactor: 将多主题功能从 pinia 抽离为 hook
This commit is contained in:
parent
e41d1f21a5
commit
281a7bebbf
@ -1,11 +1,11 @@
|
||||
<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"
|
||||
|
||||
const appStore = useAppStore()
|
||||
const { initTheme } = useTheme()
|
||||
|
||||
/** 初始化主题 */
|
||||
appStore.initTheme()
|
||||
initTheme()
|
||||
/** 将 Element-Plus 的语言设置为中文 */
|
||||
const locale = zhCn
|
||||
</script>
|
||||
|
@ -1,17 +1,12 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from "vue"
|
||||
import { useAppStore } from "@/store/modules/app"
|
||||
import themeList from "@/config/theme"
|
||||
import type { ThemeName } from "@/config/theme"
|
||||
import { useTheme } from "@/hooks/useTheme"
|
||||
import type { ThemeName } from "@/hooks/useTheme"
|
||||
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) => {
|
||||
appStore.setTheme(name)
|
||||
setTheme(name)
|
||||
}
|
||||
</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 { defineStore } from "pinia"
|
||||
import { getSidebarStatus, getActiveThemeName, setSidebarStatus, setActiveThemeName } from "@/utils/cache/localStorage"
|
||||
import type { ThemeName } from "@/config/theme"
|
||||
import { getSidebarStatus, setSidebarStatus } from "@/utils/cache/localStorage"
|
||||
|
||||
export enum DeviceType {
|
||||
Mobile,
|
||||
@ -13,18 +12,12 @@ interface ISidebar {
|
||||
withoutAnimation: boolean
|
||||
}
|
||||
|
||||
const setClassName = (value: ThemeName) => {
|
||||
document.documentElement.className = value
|
||||
}
|
||||
|
||||
export const useAppStore = defineStore("app", () => {
|
||||
const sidebar: ISidebar = reactive({
|
||||
opened: getSidebarStatus() !== "closed",
|
||||
withoutAnimation: false
|
||||
})
|
||||
const device = ref<DeviceType>(DeviceType.Desktop)
|
||||
/** 正在应用的主题的名字 */
|
||||
const activeThemeName = ref<ThemeName>(getActiveThemeName() || "normal")
|
||||
|
||||
const toggleSidebar = (withoutAnimation: boolean) => {
|
||||
sidebar.opened = !sidebar.opened
|
||||
@ -43,17 +36,6 @@ export const useAppStore = defineStore("app", () => {
|
||||
const toggleDevice = (value: DeviceType) => {
|
||||
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 */
|
||||
|
||||
import CacheKey from "@/constants/cacheKey"
|
||||
import type { ThemeName } from "@/config/theme"
|
||||
import type { ThemeName } from "@/hooks/useTheme"
|
||||
|
||||
export const getSidebarStatus = () => {
|
||||
return localStorage.getItem(CacheKey.SIDEBAR_STATUS)
|
||||
|
Loading…
x
Reference in New Issue
Block a user