Миграция с Element Plus

Архитектурные отличия

Naive UI и Element Plus используют разные подходы к организации компонентов. В Element Plus компоненты ориентированы на глобальное подключение стилей и директив, в то время как Naive UI полностью построен на реактивной модели Vue 3 с Composition API, что позволяет гибко управлять состояниями и стилями на уровне отдельных компонентов. Это означает, что при миграции необходимо учитывать следующие изменения:

  • Стилизация компонентов осуществляется через пропсы и CSS-переменные, а не через глобальные SCSS-файлы.
  • Темизация выполняется через объект theme в Naive UI, который можно передавать в провайдер NConfigProvider.
  • Композиция компонентов более модульная: вместо монолитных компонентов Element Plus рекомендуется использовать маленькие, независимые части, управляемые через реактивные состояния.

Импорт и регистрация компонентов

В Element Plus часто используется глобальный импорт всех компонентов:

import ElementPlus from 'element-plus';
import 'element-plus/dist/index.css';
app.use(ElementPlus);

Naive UI предлагает поэлементный импорт, что снижает размер бандла:

import { create, NButton, NInput } from 'naive-ui';

const naive = create({
  components: [NButton, NInput]
});

app.use(naive);

Важно отметить, что Naive UI позволяет динамически подключать только те компоненты, которые реально используются в проекте, что делает приложение более производительным.

Замена базовых компонентов

Кнопки

Element Plus:

<el-button type="primary" size="medium">Сохранить</el-button>

Naive UI:

<n-button type="primary" size="medium">Сохранить</n-button>

Различие заключается в том, что Naive UI поддерживает больше опций кастомизации через пропсы round, ghost и quaternary, а также интеграцию с темизацией через CSS-переменные.

Поля ввода

Element Plus:

<el-input v-model="value" placeholder="Введите текст"></el-input>

Naive UI:

<n-input v-model:value="value" placeholder="Введите текст" clearable></n-input>

Особенность Naive UI — реактивные пропсы v-model:value, v-model:focus, что даёт более детальный контроль за состоянием.

Списки и таблицы

Таблицы в Naive UI обладают иным API:

Element Plus:

<el-table :data="tableData">
  <el-table-column prop="name" label="Имя"></el-table-column>
  <el-table-column prop="age" label="Возраст"></el-table-column>
</el-table>

Naive UI:

<n-data-table :columns="columns" :data="tableData"></n-data-table>

columns — это массив объектов, где каждый объект описывает колонку:

const columns = [
  {
    title: 'Имя',
    key: 'name'
  },
  {
    title: 'Возраст',
    key: 'age'
  }
];

Naive UI поддерживает слоты для кастомного рендера ячеек, что позволяет создавать более гибкие таблицы без сложных шаблонов.

Модальные окна и уведомления

Naive UI заменяет глобальные методы Element Plus (this.$message, this.$notify) на инстансы функций и реактивные провайдеры:

import { message } from 'naive-ui';

message.success('Операция выполнена');

Для модальных окон используется NDialogProvider и хук useDialog:

import { useDialog } from 'naive-ui';

const dialog = useDialog();
dialog.info({
  title: 'Информация',
  content: 'Сообщение для пользователя'
});

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

Формы и валидация

Naive UI поддерживает систему валидации через пропсы компонентов и их состояние:

<n-form :model="form" :rules="rules" ref="formRef">
  <n-form-item label="Имя" path="name">
    <n-input v-model:value="form.name"></n-input>
  </n-form-item>
</n-form>

rules определяются как объект с функциями-валидаторами:

const rules = {
  name: [
    { required: true, message: 'Имя обязательно', trigger: 'blur' }
  ]
};

В отличие от Element Plus, Naive UI делает акцент на реактивность и локальное управление состоянием формы, что упрощает тестирование и повторное использование компонентов.

Темизация и кастомные стили

Naive UI использует объект themeOverrides:

import { create, NConfigProvider } from 'naive-ui';

const naive = create({
  components: [NButton],
  themeOverrides: {
    common: {
      primaryColor: '#4caf50',
      textColorBase: '#333'
    },
    Button: {
      borderRadius: '6px'
    }
  }
});

app.use(naive);

В отличие от Element Plus, изменение темы не требует переопределения глобальных CSS-классов — достаточно передать объект настроек провайдеру.

Пошаговая стратегия миграции

  1. Определить компоненты, используемые в проекте на Element Plus.
  2. Подключить соответствующие компоненты Naive UI через поэлементный импорт.
  3. Переписать шаблоны компонентов, учитывая новые пропсы и слоты.
  4. Перенести стили и цвета в themeOverrides и удалить глобальные SCSS-файлы Element Plus.
  5. Обновить уведомления, диалоги и модальные окна на новый реактивный API.
  6. Переписать формы и валидацию с учётом реактивной модели Naive UI.
  7. Тестировать каждый компонент локально перед полной заменой в приложении.

Миграция с Element Plus на Naive UI требует внимательного подхода к структуре компонентов, реактивности и кастомизации, но даёт существенные преимущества в производительности, гибкости темизации и поддержке Composition API.