JAVASCRIPT

Implement Dynamic Theming with Dark Mode Toggle in Vue 3

Enable dynamic theme switching, such as dark mode, in your Vue 3 application using CSS custom properties (variables) controlled by a Vue component.

// src/App.vue
<template>
  <div :class="['theme-wrapper', currentTheme]">
    <h1>Dynamic Theming in Vue 3</h1>
    <p>This content changes based on the active theme.</p>
    <button @click="toggleTheme">
      Switch to {{ currentTheme === 'light-theme' ? 'Dark' : 'Light' }} Mode
    </button>
    <div class="card">
      <h3>A Card Element</h3>
      <p>This card also respects the theme.</p>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';

const currentTheme = ref(localStorage.getItem('theme') || 'light-theme');

const toggleTheme = () => {
  currentTheme.value = currentTheme.value === 'light-theme' ? 'dark-theme' : 'light-theme';
  localStorage.setItem('theme', currentTheme.value);
  applyTheme(currentTheme.value);
};

const applyTheme = (theme) => {
  const root = document.documentElement;
  if (theme === 'dark-theme') {
    root.style.setProperty('--bg-color', '#282c34');
    root.style.setProperty('--text-color', '#f0f2f5');
    root.style.setProperty('--card-bg', '#3a404c');
    root.style.setProperty('--button-bg', '#61dafb');
    root.style.setProperty('--button-text', '#282c34');
  } else {
    root.style.setProperty('--bg-color', '#f0f2f5');
    root.style.setProperty('--text-color', '#282c34');
    root.style.setProperty('--card-bg', '#ffffff');
    root.style.setProperty('--button-bg', '#42b983');
    root.style.setProperty('--button-text', '#ffffff');
  }
};

onMounted(() => {
  // Apply initial theme on mount
  applyTheme(currentTheme.value);
});
</script>

<style>
/* Define default (light) theme variables */
:root {
  --bg-color: #f0f2f5;
  --text-color: #282c34;
  --card-bg: #ffffff;
  --button-bg: #42b983;
  --button-text: #ffffff;
}

body {
  margin: 0;
  font-family: Arial, sans-serif;
  background-color: var(--bg-color);
  color: var(--text-color);
  transition: background-color 0.3s ease, color 0.3s ease;
}

.theme-wrapper {
  padding: 20px;
  min-height: 100vh;
}

.card {
  background-color: var(--card-bg);
  color: var(--text-color);
  padding: 20px;
  margin-top: 20px;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  transition: background-color 0.3s ease, color 0.3s ease;
}

button {
  background-color: var(--button-bg);
  color: var(--button-text);
  border: none;
  padding: 10px 15px;
  border-radius: 5px;
  cursor: pointer;
  margin-top: 10px;
  transition: background-color 0.3s ease, color 0.3s ease;
}

button:hover {
  opacity: 0.9;
}
</style>
How it works: This snippet demonstrates how to implement a dynamic theme switcher, like dark mode, in a Vue 3 application. It leverages CSS custom properties (variables) defined on the `:root` element. The `currentTheme` reactive reference stores the active theme, persisted in `localStorage`. The `applyTheme` function programmatically updates the CSS variables on `document.documentElement` to switch between light and dark modes, ensuring a consistent look across the application. The `onMounted` hook applies the initial theme, and the `toggleTheme` function handles the switching logic.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs