Skip to content

Commit

Permalink
💄 修改主题配置功能
Browse files Browse the repository at this point in the history
  • Loading branch information
Mikasa33 committed Jun 12, 2024
1 parent 9218e3e commit 5705862
Show file tree
Hide file tree
Showing 14 changed files with 128 additions and 92 deletions.
5 changes: 1 addition & 4 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
<script setup lang="ts">
import { cloneDeep } from 'lodash-es'
import { themeSetting } from '~/settings/theme'
const { setting } = useThemeSetting({ initialValue: cloneDeep(themeSetting) })
const { setting } = storeToRefs(useThemeStore())
const configProviderProps = useNaiveConfigProvider({
themeOverrides: {
Expand Down
19 changes: 16 additions & 3 deletions src/composables/useNaiveConfigProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ export interface UseNaiveConfigProviderOptions {
* n-config-provider 被渲染成的元素
*/
tag?: ConfigProviderProps['tag']
/**
* 是否使用全局样式组件
*/
globalStyle?: boolean
/**
* 主题模式
*/
Expand All @@ -70,7 +74,12 @@ export interface UseNaiveConfigProviderOptions {
darkThemeOverrides?: MaybeRefOrGetter<GlobalThemeOverrides | null>
}

export interface UseNaiveConfigProviderReturn extends ConfigProviderProps {}
export interface UseNaiveConfigProviderReturn extends ConfigProviderProps {
/**
* 是否使用全局样式组件
*/
globalStyle?: boolean
}

export function useNaiveConfigProvider(options: UseNaiveConfigProviderOptions = {}): UseNaiveConfigProviderReturn {
const {
Expand All @@ -83,8 +92,12 @@ export function useNaiveConfigProvider(options: UseNaiveConfigProviderOptions =
...opts
} = options

const mode = useColorMode({ initialValue: themeMode })
const isDark = computed(() => mode.value === 'dark')
const { isDark } = storeToRefs(useThemeStore())
const { toggleMode } = useThemeStore()

if (themeMode)
toggleMode(toValue(themeMode))

const theme = computed(() => isDark.value ? darkTheme : null)

const currentThemeOverrides = computed(() => {
Expand Down
2 changes: 1 addition & 1 deletion src/composables/useNaiveDiscreteApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export interface UseNaiveDiscreteApiReturn {
* Naive UI 脱离上下文的 API
*/
export function useNaiveDiscreteApi(options: UseNaiveDiscreteApiOptions = {}): UseNaiveDiscreteApiReturn {
const { setting } = useThemeSetting()
const { setting } = storeToRefs(useThemeStore())

const configProviderProps = useNaiveConfigProvider({
lightThemeOverrides: computed(() => ({
Expand Down
47 changes: 0 additions & 47 deletions src/composables/useThemeSetting.ts

This file was deleted.

48 changes: 48 additions & 0 deletions src/layouts/components/header/Breadcrumb.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<script setup lang="ts">
import { menus } from '~/settings/menu'
const route = useRoute()
const router = useRouter()
const breadcrumbs = computed(() => {
return [
...findParentNodes(menus, route.path),
{
path: route.path,
label: route.meta.title,
icon: route.meta.icon,
},
]
})
function goHome() {
router.push('/')
}
</script>

<template>
<NBreadcrumb class="h-32px [&_ul]:flex-center [&_.n-breadcrumb-item\\_\\_separator]:leading-none">
<NBreadcrumbItem
v-if="route.path !== '/'"
@click="goHome"
>
<div class="h-24px w-24px flex-center">
<div class="i-icon-park-outline-home" />
</div>
</NBreadcrumbItem>
<NBreadcrumbItem
v-for="(item, index) in breadcrumbs"
:key="index"
:clickable="false"
>
<div class="h-24px flex-center px-4px">
<div
v-if="item.icon"
:class="item.icon"
class="mr-8px"
/>
<div>{{ item.label }}</div>
</div>
</NBreadcrumbItem>
</NBreadcrumb>
</template>
2 changes: 1 addition & 1 deletion src/layouts/components/header/CollapseButton.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script setup lang="ts">
import HeaderButton from '../header/HeaderButton.vue'
const { setting } = useThemeSetting()
const { setting } = storeToRefs(useThemeStore())
const collapsed = computed(() => setting.value.sider.collapsed)
function toggle() {
Expand Down
8 changes: 3 additions & 5 deletions src/layouts/components/header/HeaderButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ const emits = defineEmits<{
click: []
}>()
const { setting } = useThemeSetting()
const mode = useColorMode()
const isDark = computed(() => mode.value === 'dark')
const { isDark, setting } = storeToRefs(useThemeStore())
function handleClick() {
emits('click')
Expand All @@ -17,9 +15,9 @@ function handleClick() {
<template #trigger>
<div
:class="{
'hover:bg-#ffffff1f': !isDark && setting?.header.inverted,
'hover:bg-#ffffff1f active:bg-#ffffff14': !isDark && setting?.header.inverted,
}"
class="h-32px w-32px flex-center cursor-pointer rounded-8px bg-#2e33380d transition-300 dark:bg-#ffffff14 hover:bg-#2e333817 dark:hover:bg-#ffffff1f"
class="h-32px w-32px flex-center cursor-pointer rounded-8px bg-#2e33380d transition-300 active:bg-#2e333821 dark:(bg-#ffffff14 active:bg-#ffffff14 hover:bg-#ffffff1f) hover:bg-#2e333817"
@click="handleClick"
>
<slot name="trigger" />
Expand Down
15 changes: 5 additions & 10 deletions src/layouts/components/header/LayoutSetting.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,13 @@ defineProps<{
const show = defineModel<boolean>('show')
const message = useMessage()
const { store } = useColorMode()
const isDark = computed(() => store.value === 'dark')
const { setting } = useThemeSetting()
const { isDark, setting } = storeToRefs(useThemeStore())
const { toggleMode } = useThemeStore()
const { copy } = useClipboard()
async function handleUpdateValue(val: 'light' | 'dark' | 'auto') {
store.value = val
setting.value.themeMode = val
}
function handleResetSetting() {
setting.value = cloneDeep(themeSetting)
toggleMode(setting.value.themeMode)
message.success('重置成功')
}
Expand All @@ -46,10 +41,10 @@ function handleCopySetting() {
主题模式
</NDivider>
<NTabs
:value="store"
:value="setting.themeMode"
type="segment"
class="mb-12px"
@update:value="handleUpdateValue"
@update:value="toggleMode"
>
<NTab name="light">
<div class="i-icon-park-outline-sun-one text-16px" />
Expand Down
9 changes: 3 additions & 6 deletions src/layouts/components/header/ThemeModeButton.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
<script setup lang="ts">
import HeaderButton from './HeaderButton.vue'
const mode = useColorMode()
const isDark = computed(() => mode.value === 'dark')
function toggle() {
mode.value = isDark.value ? 'light' : 'dark'
}
const { isDark } = storeToRefs(useThemeStore())
const { toggleMode } = useThemeStore()
</script>

<template>
<HeaderButton @click="toggle">
<HeaderButton @click="toggleMode(isDark ? 'light' : 'dark')">
<template #trigger>
<div :class="isDark ? 'i-icon-park-outline-moon' : 'i-icon-park-outline-sun-one'" />
</template>
Expand Down
8 changes: 3 additions & 5 deletions src/layouts/components/header/UserDropdown.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
<script setup lang="ts">
const { setting } = useThemeSetting()
const mode = useColorMode()
const isDark = computed(() => mode.value === 'dark')
const { isDark, setting } = storeToRefs(useThemeStore())
const options = [
{
Expand All @@ -28,9 +26,9 @@ const options = [
>
<div
:class="{
'hover:bg-#ffffff1f': !isDark && setting?.header.inverted,
'hover:bg-#ffffff1f active:bg-#ffffff14': !isDark && setting?.header.inverted,
}"
class="h-42px max-w-150px flex-center cursor-pointer rounded-full bg-#2e33380d px-8px transition-300 dark:bg-#ffffff14 hover:bg-#2e333817 dark:hover:bg-#ffffff1f"
class="h-42px max-w-150px flex-center cursor-pointer rounded-full bg-#2e33380d px-8px transition-300 active:bg-#2e333821 dark:(bg-#ffffff14 active:bg-#ffffff14 hover:bg-#ffffff1f) hover:bg-#2e333817"
>
<NAvatar
src="https://avatars.githubusercontent.com/u/108928776?s=80&v=4"
Expand Down
2 changes: 1 addition & 1 deletion src/layouts/components/sider/Logo.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
const router = useRouter()
const { setting } = useThemeSetting()
const { setting } = storeToRefs(useThemeStore())
function goHome() {
router.push('/')
Expand Down
6 changes: 3 additions & 3 deletions src/layouts/default.vue
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
<script setup lang="ts">
import Logo from './components/sider/Logo.vue'
import Menu from './components/sider/Menu.vue'
import Breadcrumb from './components/header/Breadcrumb.vue'
import CollapseButton from './components/header/CollapseButton.vue'
import FullscreenButton from './components/header/FullscreenButton.vue'
import ThemeModeButton from './components/header/ThemeModeButton.vue'
import ThemeSettingButton from './components/header/ThemeSettingButton.vue'
import UserDropdown from './components/header/UserDropdown.vue'
const mode = useColorMode()
const isDark = computed(() => mode.value === 'dark')
const { setting } = useThemeSetting()
const { isDark, setting } = storeToRefs(useThemeStore())
</script>

<template>
Expand Down Expand Up @@ -50,6 +49,7 @@ const { setting } = useThemeSetting()
class="transition-300 transition-property-margin"
>
<CollapseButton />
<Breadcrumb />
</NFlex>
<NFlex
align="center"
Expand Down
17 changes: 11 additions & 6 deletions src/router.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
import type { LoadingBarApi } from 'naive-ui'
import { createRouter, createWebHistory } from 'vue-router/auto'
import { setupLayouts } from 'virtual:generated-layouts'

const { loadingBar } = useNaiveDiscreteApi()
import { routes } from 'vue-router/auto-routes'

export const router = createRouter({
history: createWebHistory(),
extendRoutes: (routes: any) => setupLayouts(routes),
routes: setupLayouts(routes),
})

let loading: LoadingBarApi

router.beforeEach(() => {
const { setting } = useThemeSetting()
const { setting } = storeToRefs(useThemeStore())

if (setting.value.page.loadingBar)
if (setting.value.page.loadingBar) {
const { loadingBar } = useNaiveDiscreteApi()
loading = loadingBar
loadingBar.start()
}

return true
})

router.afterEach(() => {
loadingBar.finish()
loading?.finish()

return true
})
32 changes: 32 additions & 0 deletions src/stores/theme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { cloneDeep } from 'lodash-es'
import { themeSetting } from '~/settings/theme'

export const useThemeStore = defineStore('a4v-store-theme', () => {
const { store: mode } = useColorMode()

const isDark = computed(() => mode.value === 'dark')

const setting = useStorage(
'y-pro-user-info',
cloneDeep(themeSetting),
undefined,
{
serializer: {
read: (val: string) => (val ? JSON.parse(val) : null),
write: (val: any) => JSON.stringify(val),
},
},
)

function toggleMode(val: 'dark' | 'light' | 'auto') {
setting.value.themeMode = val
mode.value = val
}

return {
mode,
isDark,
setting,
toggleMode,
}
})

0 comments on commit 5705862

Please sign in to comment.