Динамическое переключение тем

Naive UI предоставляет мощный механизм для работы с тёмными и светлыми темами, позволяя динамически менять визуальное оформление компонентов без перезагрузки страницы. Центральным элементом управления темой является createTheme, а также использование провайдера n-config-provider, через который можно централизованно управлять глобальными настройками интерфейса.


Подключение и базовая настройка

Для начала необходимо импортировать ConfigProvider из Naive UI:

import { createApp, reactive } from 'vue'
import { create naive, NButton, NConfigProvider } from 'naive-ui'

const app = createApp({
  setup() {
    const theme = reactive({ isDark: false })
    return { theme }
  },
  template: `
    <n-config-provider :theme-overrides="theme">
      <n-button>Пример кнопки</n-button>
    </n-config-provider>
  `
})

app.mount('#app')

В примере theme — это реактивный объект, который может содержать либо предопределённые темы, либо собственные переопределения цветов и настроек компонентов.


Использование предопределённых тем

Naive UI предоставляет готовые темы lightTheme и darkTheme. Их можно подключить напрямую через ConfigProvider:

import { lightTheme, darkTheme, NConfigProvider } from 'naive-ui'

const theme = reactive({ currentTheme: lightTheme })

function toggleTheme() {
  theme.currentTheme = theme.currentTheme === lightTheme ? darkTheme : lightTheme
}

Компонент NConfigProvider автоматически применяет выбранную тему ко всем вложенным компонентам.


Переопределение отдельных переменных темы

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

const customTheme = reactive({
  common: {
    primaryColor: '#4caf50',
    textColor1: '#333333'
  },
  Button: {
    color: '#4caf50',
    colorPressed: '#388e3c'
  }
})

Передача объекта customTheme в NConfigProvider:

<n-config-provider :theme-overrides="customTheme">
  <n-button>Кастомная кнопка</n-button>
</n-config-provider>

Таким образом можно динамически менять отдельные свойства темы в зависимости от состояния приложения или выбора пользователя.


Динамическая смена темы через реактивные свойства

Самый распространённый способ — использование реактивного состояния Vue для управления темой:

import { reactive, computed } from 'vue'
import { NConfigProvider, lightTheme, darkTheme } from 'naive-ui'

const state = reactive({
  darkMode: false
})

const currentTheme = computed(() => state.darkMode ? darkTheme : lightTheme)

При изменении state.darkMode все компоненты внутри NConfigProvider автоматически обновляют свои стили без перезагрузки страницы.

<n-config-provider :theme="currentTheme">
  <n-button @click="state.darkMode = !state.darkMode">
    Переключить тему
  </n-button>
</n-config-provider>

Применение пользовательских тем совместно с предопределёнными

Можно объединять переопределения и базовую тему, чтобы сохранить преимущества готовой темы и одновременно подстраивать цвета под бренд:

const customOverrides = reactive({
  Button: {
    color: '#ff5722',
    colorPressed: '#e64a19'
  }
})

const themeWithOverrides = computed(() => ({
  ... (state.darkMode ? darkTheme : lightTheme),
  ...customOverrides
}))

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


Управление темой на уровне всего приложения

В крупных приложениях удобно создавать глобальный провайдер темы в main.js:

import { createApp, reactive, computed } from 'vue'
import { NConfigProvider, lightTheme, darkTheme } from 'naive-ui'
import App from './App.vue'

const app = createApp(App)

const state = reactive({ darkMode: false })
const theme = computed(() => state.darkMode ? darkTheme : lightTheme)

app.provide('themeState', state)

app.component('NConfigProvider', {
  setup(_, { slots }) {
    return () => <NConfigProvider theme={theme.value}>{slots.default()}</NConfigProvider>
  }
})

app.mount('#app')

Это позволяет любому компоненту внутри приложения получать состояние темы через inject и менять её динамически.


Советы по производительности

  • Использовать computed для объединения базовой темы и переопределений — это предотвращает лишние перерендеры компонентов.
  • Для больших приложений рекомендуется хранить состояние темы в Pinia или Vuex, чтобы иметь централизованный контроль.
  • Переопределения лучше группировать по компонентам (Button, Input, Card) и общим цветам (primaryColor, textColor1), чтобы избежать избыточного кода.

Итоговые возможности

Динамическое переключение тем в Naive UI позволяет:

  • Мгновенно менять интерфейс между светлой и тёмной темой.
  • Переопределять отдельные переменные стилей компонентов.
  • Комбинировать предопределённые темы и пользовательские кастомизации.
  • Управлять темой на уровне всего приложения через реактивные состояния.

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