Vue.jsでのダークモードの実装:CSSカスタムプロパティやprefers-color-schemeメディアクエリを活用

Vue.jsでのダークモードの実装:CSSカスタムプロパティやprefers-color-schemeメディアクエリを活用

Vue.jsとCSSカスタムプロパティ、prefers-color-schemeメディアクエリを活用することで、ユーザーのシステム設定に基づくダークモード対応や、切り替え可能なダークモードを効率的に実装できる。

 

1. プロジェクト環境のセットアップ

新しいVue.jsプロジェクトを作成し、基本的なCSS変数を準備する。

npm install -g @vue/cli
vue create dark-mode-app
cd dark-mode-app

2. CSSカスタムプロパティの定義

CSS変数を使用して、ライトモードとダークモード用のテーマカラーを定義する。

:root {
  --background-color: #ffffff;
  --text-color: #000000;
}

[data-theme="dark"] {
  --background-color: #121212;
  --text-color: #ffffff;
}

3. prefers-color-schemeメディアクエリの活用

OSのテーマ設定に応じて自動でテーマを適用する。

@media (prefers-color-scheme: dark) {
  :root {
    --background-color: #121212;
    --text-color: #ffffff;
  }
}

4. Vueコンポーネントでテーマを適用

Vueコンポーネントでテーマを適用し、スタイルを反映させる。

<template>
  <div :class="{ dark: isDarkMode }">
    <h1>ダークモード対応アプリ</h1>
    <button @click="toggleTheme">テーマ切り替え</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isDarkMode: false,
    };
  },
  methods: {
    toggleTheme() {
      this.isDarkMode = !this.isDarkMode;
      document.documentElement.setAttribute('data-theme', this.isDarkMode ? 'dark' : 'light');
    },
  },
};
</script>

5. ローカルストレージでテーマを永続化

ユーザーのテーマ選択をローカルストレージに保存する。

mounted() {
  const savedTheme = localStorage.getItem('theme');
  if (savedTheme) {
    document.documentElement.setAttribute('data-theme', savedTheme);
    this.isDarkMode = savedTheme === 'dark';
  }
},
methods: {
  toggleTheme() {
    this.isDarkMode = !this.isDarkMode;
    const theme = this.isDarkMode ? 'dark' : 'light';
    document.documentElement.setAttribute('data-theme', theme);
    localStorage.setItem('theme', theme);
  },
}

6. スタイルを適用

CSS変数を使用して背景色やテキスト色を適用する。

body {
  background-color: var(--background-color);
  color: var(--text-color);
}

7. テーマアイコンの切り替え

ライトモードとダークモードで異なるアイコンを表示する。

<template>
  <button @click="toggleTheme">
    <span v-if="isDarkMode">🌙</span>
    <span v-else>☀️</span>
  </button>
</template>

8. コンポーネント単位のテーマ適用

特定のコンポーネントにのみテーマを適用する。

<template>
  <div class="themed-component">テーマ対応コンポーネント</div>
</template>

<style scoped>
.themed-component {
  background-color: var(--background-color);
  color: var(--text-color);
}
</style>

9. Vuexでテーマ状態を管理

Vuexを使ってテーマの状態を集中管理する。

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    theme: 'light',
  },
  mutations: {
    SET_THEME(state, theme) {
      state.theme = theme;
    },
  },
  actions: {
    toggleTheme({ commit, state }) {
      const newTheme = state.theme === 'light' ? 'dark' : 'light';
      commit('SET_THEME', newTheme);
      document.documentElement.setAttribute('data-theme', newTheme);
      localStorage.setItem('theme', newTheme);
    },
  },
});

10. テーマ切り替えアニメーション

テーマ切り替え時にアニメーションを追加する。

body {
  transition: background-color 0.3s, color 0.3s;
}

11. prefers-color-schemeのデフォルト設定

デフォルトでOSのテーマ設定を優先する。

mounted() {
  const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
  const savedTheme = localStorage.getItem('theme');
  const theme = savedTheme || (prefersDark ? 'dark' : 'light');
  document.documentElement.setAttribute('data-theme', theme);
  this.isDarkMode = theme === 'dark';
}

12. アプリケーションのデプロイ

完成したダークモード対応アプリをデプロイする。

npm run build
netlify deploy