Персистентность выбора темы

В приложениях на Quasar Framework поддержка выбора темы (светлой или тёмной) является ключевым аспектом пользовательского интерфейса, обеспечивая комфортное взаимодействие с приложением в зависимости от предпочтений пользователя. Quasar предоставляет встроенные механизмы для управления темами и их персистентного сохранения, что позволяет автоматически применять выбранную тему при повторном посещении приложения.


Управление темами через Quasar

Quasar использует объект $q для доступа к глобальным параметрам, включая тему. Основные методы и свойства для работы с темой:

  • $q.dark.isActive — возвращает true, если активна тёмная тема, false для светлой.
  • $q.dark.set(true | false) — принудительно устанавливает тёмную (true) или светлую (false) тему.
  • $q.dark.toggle() — переключает текущую тему на противоположную.

Пример простого переключателя темы:

<template>
  <q-toggle 
    v-model="isDark" 
    label="Тёмная тема" 
    @update:model-value="toggleTheme"
/>
</template>

<script>
export default {
  data() {
    return {
      isDark: this.$q.dark.isActive
    }
  },
  methods: {
    toggleTheme(val) {
      this.$q.dark.set(val)
    }
  }
}
</script>

В этом примере используется v-model для двусторонней привязки состояния переключателя к текущей теме.


Сохранение темы между сессиями

Для персистентного хранения предпочтений пользователя можно использовать localStorage или Quasar LocalStorage, который является обёрткой для работы с локальным хранилищем и упрощает сериализацию и десериализацию данных.

Использование Quasar LocalStorage

import { LocalStorage } from 'quasar'

export default {
  data() {
    return {
      isDark: LocalStorage.getItem('theme') === 'dark'
    }
  },
  watch: {
    isDark(newVal) {
      this.$q.dark.set(newVal)
      LocalStorage.set('theme', newVal ? 'dark' : 'light')
    }
  },
  mounted() {
    this.$q.dark.set(this.isDark)
  }
}

В этом примере:

  • При загрузке приложения читается сохранённая тема.
  • При изменении переключателя значение записывается в LocalStorage.
  • При монтировании компонента устанавливается соответствующая тема.

Использование watch гарантирует, что изменение состояния темы автоматически синхронизируется с локальным хранилищем.


Автоматическое определение системной темы

Quasar позволяет синхронизировать тему с системными настройками пользователя с помощью метода $q.dark.set(true, 'auto'), где 'auto' означает автоматическое определение:

this.$q.dark.set(true, 'auto') // Включение авто-режима

Это полезно для мобильных приложений или веб-приложений, где предпочтения системы могут отличаться от ранее сохранённых значений. Можно комбинировать автоматическое определение с сохранением выбора пользователя:

mounted() {
  const savedTheme = LocalStorage.getItem('theme')
  if (savedTheme) {
    this.$q.dark.set(savedTheme === 'dark')
  } else {
    this.$q.dark.set(true, 'auto')
  }
}

Интеграция с Vuex для глобального состояния

Если приложение использует Vuex, тему можно хранить в глобальном состоянии для более гибкого управления между компонентами:

// store/theme.js
export default {
  state: () => ({
    dark: LocalStorage.getItem('theme') === 'dark'
  }),
  mutations: {
    setTheme(state, value) {
      state.dark = value
      LocalStorage.set('theme', value ? 'dark' : 'light')
    }
  },
  actions: {
    toggleTheme({ commit, state }) {
      commit('setTheme', !state.dark)
    }
  }
}

Применение темы в основном компоненте:

watch: {
  '$store.state.theme.dark'(val) {
    this.$q.dark.set(val)
  }
},
mounted() {
  this.$q.dark.set(this.$store.state.theme.dark)
}

Преимущество такого подхода — синхронизация состояния темы между всеми компонентами приложения без необходимости повторять код переключения в каждом из них.


Использование Cookies для серверного рендеринга

Для приложений на Nuxt + Quasar или SSR рекомендуется использовать cookies, чтобы тема была доступна на сервере и клиенте одновременно:

import Cookies from 'js-cookie'

export default {
  data() {
    return {
      isDark: Cookies.get('theme') === 'dark'
    }
  },
  watch: {
    isDark(val) {
      this.$q.dark.set(val)
      Cookies.set('theme', val ? 'dark' : 'light')
    }
  },
  mounted() {
    this.$q.dark.set(this.isDark)
  }
}

Такой подход обеспечивает согласованное отображение темы при первой загрузке страницы, минимизируя визуальные “мигания” между светлой и тёмной темой.


Рекомендации по UX

  • Хранить тему в локальном хранилище или Vuex, чтобы изменения применялись мгновенно.
  • Предоставлять пользователю переключатель темы в доступном месте, например, в шапке приложения.
  • Поддерживать автоматическое определение системной темы как запасной вариант.
  • При SSR использовать cookies для корректной начальной отрисовки темы.

Персистентность темы в Quasar — это комбинация правильного управления состоянием, сохранения данных в хранилище и адаптации к системным настройкам пользователя. Такой подход обеспечивает плавный, согласованный UX и позволяет легко масштабировать приложение.