Темы, сделанные как надо.
Наконец-то.
Я нагляделся на Vue-приложения, утопающие в CSS-спагетти, — хватит на всю жизнь. Знакомая картина: лепишь класс .dark на html, молишься, чтобы переопределения не конфликтовали, а потом клиент требует «осенний оранжевый» или «корпоративный бирюзовый» — и всё летит к чертям. vue-multiple-themes v4 — ключевое слово здесь, друзья — вытаскивает из этой ямы с помощью CSS-переменных, реактивных composables и пресетов, которые реально работают в Vue 2 и 3.
Я строю UI на Vue годами, и один паттерн всплывает постоянно: нужно больше, чем светло/тёмно. Клиенты хотят сезонные темы, брендовые палитры и контрастность для доступности.
Автор попал в точку. Обычные переключатели? Нормально для светло-тёмной пары. А попробуй масштабировать до семи — light, dark, sepia, ocean, forest, sunset, winter — и ты в аду селекторов: дублирующиеся правила, войны специфичности, никаких простых проверок WCAG. Эта библиотека переворачивает всё с ног на голову.
Она впрыскивает переменные –vmt-* прямо в целевой элемент. Меняешь тему? Значения обновляются в одном слое каскада. Без перерендеров. Реактивный composable useTheme() пузырится куда угодно. Плагин для Tailwind превращает эти переменные в утилиты вроде bg-vmt-surface. А утилиты для цвета — contrastRatio, autoContrast — чистые функции, безопасные для SSR, tree-shakeable.
Подключение — дело пяти минут. pnpm add vue-multiple-themes. Вставляешь в main.ts:
app.use(VueMultipleThemesPlugin, { defaultTheme: ‘dark’, strategy: ‘attribute’, persist: true, });
Дальше?
const { currentTheme, setTheme, themes } = useTheme({ themes: PRESET_THEMES });Готово. Кнопки для переключения. Переменные на html. Стилизуешь .card через var(–vmt-background). Обновления мгновенные везде.
Почему бросить свои ржавые хаки с темами?
Послушайте, если вы до сих пор вручную ковыряете CSS-переменные или — упаси боже — переключаете классы через JS, пора просыпаться. vue-multiple-themes — не хайп, а спасение от реальных мук. Семь пресетов? Light с чистым индиго. Dark с фиолетовым ударом. Sepia с тёплой пергаментной теплотой (книголюбы, радуйтесь). Океанские блюзы, лесные гринсы, закатные огни, зимний лёд — всё настроено, из коробки почти доступно.
А убийственная фича? Генерируй свои. const { light, dark } = generateThemePair(‘#6366f1’); Или scale = generateColorScale(‘#6366f1’, 9); Золото для SaaS. Тенант выбрал брендовый hex? Весь UI адаптируется. Хватит backlog’а с «сделайте фиолетовым».
Пользователи Tailwind: createVmtPlugin() выдаёт bg-vmt-foreground, border-vmt-border. Смена темы? Дивы перерисовываются плавно. И persist в localStorage по умолчанию. Забыл prefs юзера? Уже учтено.
Моя уникальная мысль: это эхо взлёта Tailwind — когда утилиты убили BEM-кошмары. vue-multiple-themes может стандартизировать теминг в Vue, как Tailwind — CSS. Прогноз: через год все Nuxt/VitePress-сайты забудут о кастомных хаках. Vue core даже composable заимствует.
Корпоративный спин? Ноль. Open source, без зависимостей кроме Vue. Vue 2.7+ или 3. Типизировано. Но учтите: если пресеты приковывают — форкните. Не лентяйничайте.
А доступность в vue-multiple-themes реальна?
Коротко: лучше, чем ваш средний тёмный режим на коленке.
Подробнее? WCAG-утилиты встроены. contrastRatio(‘#6366f1’, ‘#ffffff’) выдаёт 4.54. checkContrast() проверяет AA/AAA. autoContrast умно выбирает белый или чёрный. Генерация палитр? Собирает compliant шкалы.
Но — не панацея. Стилишь против переменных сам. Пропустил контраст на бордере? Твоя вина. Пресеты осторожные: зимние белые проходят AAA для крупного текста. Лесные гринсы — AA надёжно. Тестируйте брендовые, девы.
SSR-safe — никаких hydration-косяков. Фанаты Nuxt, улыбнитесь. Кастомные элементы? Стратегия: ‘attribute’, ‘class’ или ‘both’. Гибко.
Один косяк: доки кричат «plug and play», но themes по умолчанию — пресеты. Переопределить? Просто, но типы поищи. Vue