Автоматическая регистрация Vue-компонентов с уникальными именами и произвольной вложенностью

от автора

в
Время чтения: 1 мин.

В больших проектах на Vue часто приходится работать с десятками (а то и сотнями) компонентов. Их импорт и регистрация вручную быстро превращаются в рутину. Для автоматизации этого процесса существует удобный инструмент — unplugin-vue-components.

В этой статье разберём, как правильно настроить его так, чтобы:

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

Базовое использование

Устанавливаем плагин:

npm i -D unplugin-vue-components

Подключаем в vite.config.ts:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import Components from 'unplugin-vue-components/vite'

export default defineConfig({
  plugins: [
    vue(),
    Components({
      dirs: ['src/components'], // сканировать папку
      deep: true,               // искать рекурсивно
      extensions: ['vue'],
    }),
  ],
})

Теперь любой .vue-компонент из src/components можно использовать напрямую без import.


Проблема одинаковых имён

Допустим, у нас есть структура:

src/components/
  ui/
    Button.vue
  form/
    Button.vue

Если оставить всё как есть, то оба компонента будут называться <Button />, и плагин не сможет определить, какой использовать.


Решение: directoryAsNamespace

Чтобы избежать конфликтов, можно включить опцию directoryAsNamespace. В этом случае имя папки добавляется к имени компонента:

Components({
  dirs: ['src/components'],
  deep: true,
  directoryAsNamespace: true,
})

Теперь:

  • src/components/ui/Button.vue<UiButton />
  • src/components/form/Button.vue<FormButton />

Настройка глобальных пространств имён

Если для каких-то папок вы не хотите добавлять префикс, можно использовать globalNamespaces:

Components({
  dirs: ['src/components'],
  deep: true,
  directoryAsNamespace: true,
  globalNamespaces: ['ui'], // компоненты из /ui будут без префикса
})

Теперь:

  • <Button /> — это ui/Button.vue
  • <FormButton /> — это form/Button.vue

Кастомные правила именования

Если нужны более гибкие правила, можно подключить свой resolver. Например, добавлять общий префикс My:

Components({
  resolvers: [
    (name) => {
      if (name.endsWith('Button')) {
        return { importName: name, path: '@/components/form' }
      }
    },
  ],
})

Пример архитектуры проекта

Обычно удобно делить компоненты на категории и подключать их с пространствами имён:

src/components/
  ui/         # базовые элементы (кнопки, иконки, инпуты)
  form/       # компоненты для форм
  widgets/    # большие виджеты (карусели, таблицы, фильтры)
  layout/     # шапка, подвал, боковые панели

Использование в шаблонах:

<UiButton />
<FormInput />
<WidgetsCarousel />
<LayoutHeader />

Так проект остаётся структурированным, а конфликтов в названиях нет.


Итог

unplugin-vue-components позволяет полностью избавиться от ручных импортов в Vue, даже в больших проектах. А комбинация опций deep: true и directoryAsNamespace: true решает проблему произвольной вложенности и одинаковых имён.

В результате:

  • меньше кода для поддержки;
  • чистая архитектура проекта;
  • уникальные и понятные имена компонентов.

Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Сколько будет 1 + 9?