JAVASCRIPT

Vue 3 Global Theme Management with Pinia

Implement a simple Pinia store in Vue 3 to manage and persist global application themes (light/dark mode) across components, ensuring reactivity.

// stores/theme.js
import { defineStore } from 'pinia';
import { ref, computed } from 'vue';

export const useThemeStore = defineStore('theme', () => {
  const currentTheme = ref(localStorage.getItem('theme') || 'light');

  const isDarkMode = computed(() => currentTheme.value === 'dark');

  function toggleTheme() {
    currentTheme.value = isDarkMode.value ? 'light' : 'dark';
    localStorage.setItem('theme', currentTheme.value);
    document.documentElement.setAttribute('data-theme', currentTheme.value);
  }

  // Initialize theme on store creation
  document.documentElement.setAttribute('data-theme', currentTheme.value);

  return {
    currentTheme,
    isDarkMode,
    toggleTheme,
  };
});

// App.vue (or any component)
<template>
  <div :class="{'dark-mode-bg': themeStore.isDarkMode, 'light-mode-bg': !themeStore.isDarkMode}">
    <h1>Current Theme: {{ themeStore.currentTheme }}</h1>
    <button @click="themeStore.toggleTheme">Toggle Theme</button>
    <ChildComponent />
  </div>
</template>

<script setup>
import { useThemeStore } from './stores/theme';
import ChildComponent from './ChildComponent.vue';

const themeStore = useThemeStore();
</script>

<style>
/* Basic theme styles */
:root[data-theme='light'] {
  --text-color: #333;
  --bg-color: #f0f0f0;
}
:root[data-theme='dark'] {
  --text-color: #eee;
  --bg-color: #333;
}
body {
  color: var(--text-color);
  background-color: var(--bg-color);
  transition: background-color 0.3s ease, color 0.3s ease;
}
.dark-mode-bg { /* Example for demonstration */
  background-color: #2c3e50;
  color: #ecf0f1;
}
.light-mode-bg { /* Example for demonstration */
  background-color: #ffffff;
  color: #34495e;
}
</style>
How it works: This snippet demonstrates how to set up a Pinia store in Vue 3 for global theme management. It defines a reactive `currentTheme` state, a `isDarkMode` computed property, and a `toggleTheme` action. The theme is persisted in `localStorage` and applied to the `documentElement` for CSS theming. Components can then easily consume and interact with this global state using `useThemeStore()`.

Need help integrating this into your project?

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

Hire DigitalCodeLabs