Skip to content

Commit e1fe68c

Browse files
committed
fix: Fixed Dark Mode sync with system preferences (#61)
1 parent e2eaa64 commit e1fe68c

File tree

4 files changed

+45
-0
lines changed

4 files changed

+45
-0
lines changed

src/App.vue

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { storeToRefs } from 'pinia'
33
import useAppStore from '@/stores/modules/app'
44
import useRouteTransitionNameStore from '@/stores/modules/routeTransitionName'
5+
import useAutoThemeSwitcher from '@/hooks/useAutoThemeSwitcher'
56
67
useHead({
78
title: 'Vue3 Vant Mobile',
@@ -22,6 +23,12 @@ const { mode } = storeToRefs(appStore)
2223
2324
const routeTransitionNameStore = useRouteTransitionNameStore()
2425
const { routeTransitionName } = storeToRefs(routeTransitionNameStore)
26+
27+
const { initializeThemeSwitcher } = useAutoThemeSwitcher(appStore)
28+
29+
onMounted(() => {
30+
initializeThemeSwitcher()
31+
})
2532
</script>
2633

2734
<template>

src/hooks/useAutoThemeSwitcher.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import type { AppStore } from '@/stores/modules/app'
2+
3+
export default function useAutoThemeSwitcher(appStore: AppStore) {
4+
const handleAttributeChange = () => {
5+
const rootElement = document.documentElement
6+
if (rootElement.classList.contains('dark'))
7+
appStore.swithMode('dark')
8+
else
9+
appStore.swithMode('light')
10+
}
11+
12+
const observerOptions = {
13+
attributes: true,
14+
attributeFilter: ['class'],
15+
}
16+
17+
const observer = new MutationObserver(handleAttributeChange)
18+
19+
const targetElement = document.querySelector('html')
20+
21+
const initializeThemeSwitcher = () => {
22+
observer.observe(targetElement, observerOptions)
23+
}
24+
25+
return { initializeThemeSwitcher }
26+
}

src/stores/modules/app.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import { defineStore } from 'pinia'
22
import type { ConfigProviderTheme } from 'vant'
33

4+
export interface AppStore {
5+
swithMode: (val: ConfigProviderTheme) => void
6+
}
7+
48
const prefersDark
59
= window.matchMedia
610
&& window.matchMedia('(prefers-color-scheme: dark)').matches

src/views/index.vue

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@ definePage({
1111
const appStore = useAppStore()
1212
const checked = ref<boolean>(isDark.value)
1313
14+
watch(
15+
() => isDark.value,
16+
(newMode) => {
17+
checked.value = newMode
18+
},
19+
{ immediate: true },
20+
)
21+
1422
function toggle() {
1523
toggleDark()
1624
appStore.swithMode(isDark.value ? 'dark' : 'light')

0 commit comments

Comments
 (0)