Концепция тематизации в Naive UI

В Naive UI тематизация реализуется через гибкую систему токенов стилей, позволяющую централизованно управлять внешним видом компонентов. Темы представляют собой объекты, где задаются значения ключевых переменных интерфейса, таких как цвета, отступы, размеры шрифтов, тени и радиусы скругления. Такой подход обеспечивает единообразие интерфейса и упрощает поддержку приложения при масштабировании.

Основные принципы работы с темами

  1. Токены и переменные

    Темы в Naive UI строятся на базе CSS-подобных токенов. Каждый компонент использует набор предопределённых токенов для управления визуальными свойствами. Например, для кнопки это могут быть:

    • colorPrimary — основной цвет кнопки
    • colorPrimaryHover — цвет при наведении
    • fontSize — размер текста
    • borderRadius — радиус скругления углов

    Изменяя значения этих токенов, можно создавать новые визуальные стили компонентов без переписывания кода самих компонентов.

  2. Система наследования

    Темы в Naive UI поддерживают иерархическую структуру: глобальная тема может быть расширена локальной темой для отдельных компонентов или секций приложения. Это позволяет реализовать, например, светлую и тёмную тему одновременно, а также локальные изменения для специфических страниц.

    import { createTheme, NButton } from 'naive-ui';
    
    const customTheme = createTheme({
      common: {
        primaryColor: '#4caf50',
        borderRadius: '8px'
      },
      Button: {
        textColor: '#ffffff',
        color: '#4caf50',
        colorHover: '#45a049'
      }
    });
    
    <NButton theme={customTheme}>Кнопка</NButton>

    Здесь глобальные настройки (common) задают основные токены, а отдельные компоненты (Button) могут переопределять их.

Смена темы в рантайме

Naive UI поддерживает динамическую смену тем без перезагрузки страницы. Для этого используется контекст theme и провайдеры тем:

import { NConfigProvider } from 'naive-ui';
import { reactive } from 'vue';

const state = reactive({
  darkMode: false
});

<NConfigProvider theme={state.darkMode ? darkTheme : lightTheme}>
  <App />
</NConfigProvider>

Такой подход позволяет реализовать переключение между светлой и тёмной темами, а также применять пользовательские стили в зависимости от настроек интерфейса.

Локальная темизация компонентов

Каждый компонент Naive UI может иметь собственную локальную тему, которая не зависит от глобальной. Это полезно для модальных окон, панелей или карточек с индивидуальным оформлением.

<NButton themeOverrides={{
  color: '#ff5722',
  colorHover: '#e64a19'
}}>
  Локальная кнопка
</NButton>

themeOverrides позволяет переопределять любые токены только для конкретного экземпляра компонента, сохраняя глобальную тему без изменений.

Пользовательские темы и расширение токенов

Для комплексных приложений часто требуется создавать пользовательские токены, которых нет в стандартном наборе. Для этого Naive UI предоставляет возможность расширять тему через объект themeOverrides и createTheme.

const extendedTheme = createTheme({
  common: {
    primaryColor: '#2196f3',
    successColor: '#4caf50',
    infoColor: '#03a9f4',
    warningColor: '#ff9800',
    errorColor: '#f44336',
    customToken: '2px solid #2196f3'
  }
});

Компоненты могут использовать новые токены напрямую через свойство themeOverrides или в CSS через CSS переменные.

Практические рекомендации

  • Разделять глобальные и локальные токены. Глобальные задают основу дизайна, локальные — специфические визуальные решения.
  • Использовать динамическую смену тем для поддержки светлых/тёмных режимов.
  • При создании пользовательских токенов придерживаться именования в стиле camelCase для сохранения консистентности.
  • Для крупных приложений формировать модульную структуру тем, где каждая зона интерфейса может иметь собственные настройки без конфликта с глобальной темой.

Интеграция с Vue и реактивность

Темы полностью совместимы с реактивной моделью Vue. Любое изменение значения в объекте темы автоматически пересчитывает стиль компонентов, что исключает необходимость ручного обновления классов или стилей.

import { reactive } from 'vue';
import { NButton } from 'naive-ui';

const themeState = reactive({
  primaryColor: '#ff5722'
});

<NButton themeOverrides={{
  color: themeState.primaryColor
}}>
  Реактивная кнопка
</NButton>

Изменение themeState.primaryColor мгновенно обновляет цвет всех связанных компонентов, что обеспечивает полностью динамическую тематизацию интерфейса.

Заключение принципов

Система тематизации Naive UI построена на гибкой архитектуре токенов, поддерживает наследование, локальные переопределения, динамическую смену тем и интегрируется с реактивностью Vue. Такой подход делает библиотеку мощным инструментом для создания масштабируемых и настраиваемых интерфейсов с единообразной визуальной идентичностью.