在 Nuxt 3.11 建立深色模式切換器

前言

以下範例搭配 Vuetify UI 框架實作。

實作

建立 composables/useCustomTheme.js 檔。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import { useTheme } from 'vuetify';

const THEME_DARK = 'dark';
const THEME_LIGHT = 'light';

export function useCustomTheme() {
const theme = useTheme();
const localTheme = useCookie('theme');
const isDarkTheme = computed(() => theme.global.name.value === THEME_DARK);

const initTheme = () => {
const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)');
prefersDarkScheme.addEventListener('change', (event) => {
setTheme(event.matches ? THEME_DARK : THEME_LIGHT);
});
setTheme(localTheme.value || (prefersDarkScheme.matches ? THEME_DARK : THEME_LIGHT));
};

const setTheme = (v) => {
theme.global.name.value = v;
localTheme.value = v;
};

const toggleTheme = () => {
setTheme(isDarkTheme.value ? THEME_LIGHT : THEME_DARK);
};

return {
localTheme,
isDarkTheme,
initTheme,
setTheme,
toggleTheme,
};
}

建立 components/AppThemeSwitch.vue 檔。

1
2
3
4
5
6
7
8
9
10
11
12
<script setup>
const { isDarkTheme, initTheme, toggleTheme } = useCustomTheme();

initTheme();
</script>

<template>
<AppIconButton
:icon="isDarkTheme ? 'mdi-weather-night' : 'mdi-white-balance-sunny'"
@click="toggleTheme"
/>
</template>

使用。

1
<AppThemeSwitch />