😽
TypeScript & GraphQL でToDoアプリを開発する #6
⬅️前回の記事はこちら
ダークモード/ライトモード & 日本語/英語 切り替え機能を実装
⭐️ダークモード/ライトモード 切り替え機能を実装
index.vueのscript setupに追記
index.vue
import { useTheme } from 'vuetify'
const theme = useTheme()
const toggleTheme = () => {
theme.global.name.value = theme.global.name.value === 'dark' ? 'light' : 'dark'
}
index.vueのv-card-titleを修正
index.vue
<v-card-title class="d-flex justify-space-between align-center text-h6">
新しいタスク
<v-btn icon @click="toggleTheme">
<v-icon>{{ theme.global.name.value === 'dark' ? 'mdi-white-balance-sunny' : 'mdi-weather-night' }}</v-icon>
</v-btn>
</v-card-title>
vuetify.tsに icons: と theme: を追記
vuetify.ts
import { createVuetify } from 'vuetify'
import * as components from 'vuetify/components'
import * as directives from 'vuetify/directives'
import { aliases, mdi } from 'vuetify/iconsets/mdi'
// Nuxtプラグインとして Vuetify を定義
export default defineNuxtPlugin((nuxtApp) => {
// Vuetify インスタンスの作成
const vuetify = createVuetify({
components, // 全てのVuetifyコンポーネントを登録
directives, // 全てのVuetifyディレクティブを登録
ssr: true, // SSR(サーバーサイドレンダリング)対応を有効にする
icons: { // アイコン設定(mdi)
defaultSet: 'mdi',
aliases,
sets: { mdi },
},
theme: { // テーマ設定(ダーク/ライトモード切り替え)
defaultTheme: 'light',
themes: {
light: {
dark: false,
colors: {
background: '#FFFFFF',
surface: '#FFFFFF',
primary: '#1976D2',
secondary: '#424242',
error: '#FF5252',
info: '#2196F3',
success: '#4CAF50',
warning: '#FB8C00',
},
},
dark: {
dark: true,
colors: {
background: '#121212',
surface: '#1E1E1E',
primary: '#90CAF9',
secondary: '#EEEEEE',
error: '#FF5252',
info: '#2196F3',
success: '#4CAF50',
warning: '#FB8C00',
},
},
},
},
})
// 作成したVuetifyインスタンスを Nuxt アプリに組み込む
nuxtApp.vueApp.use(vuetify)
})
動作確認
🚀ダークモード/ライトモード 切り替え機能の実装が完了!!!
#6のおわりに
ダークモード/ライトモード 切り替え機能の実装 お疲れさまでした。
次回は日本語/英語の切り替え機能を実装します。
〜UIテーマは“状態”として扱うべきという話〜
今回の実装では、VuetifyのuseTheme()を用いて、UIテーマの切り替えを行いました。一見すると単純なトグル処理に見えますが、これはVueのリアクティブシステムに組み込まれた「状態管理」の一部です。
theme.global.name.value は ref と同様のリアクティブな値であり、この値を更新するとVuetifyは内部的に現在のテーマ情報(ダークモード/ライトモード)を再評価し、全コンポーネントのスタイルを即時に再描画します。
これは裏側でCSSクラスの差し替えやVuetifyのデザイントークンの切り替えが自動的に行われており、開発者は明示的にCSSを操作する必要がありません。たとえば以下のような挙動が自動的に発生します。
- <v-card>や<v-btn>などの色や背景、影の変更
- カラーパレット(primary, secondaryなど)の自動切り替え
- ダークテーマ特有のアクセントやタイポグラフィの最適化
このような「状態によるスタイル制御」は、単なる見た目の変更に留まらず、以下の観点でも有効です。
- コンポーネント設計:見た目をpropsやcomputedではなく「テーマの状態」に委ねられるため再利用性が高い
- アクセシビリティ:背景と文字色のコントラスト管理がVuetifyによって保証される
- SSR対応:初回レンダリング時にテーマ状態を考慮してスタイルが決定されるため、表示ブレが起こりにくい
テーマは見た目を切り替えるだけの機能ではなく、アプリケーションの状態として管理することで、設計の一貫性やメンテナンス性が向上します。
Discussion