CODEGURU

Vue.js и глобальная регистрация компонентов

Обычно при создании приложения на Vue у нас есть базовые компоненты, которые используются во многих местах приложения. Чаще всего это кнопки, различные элементы форм и т.д. Импортировать их каждый раз довольно утомительно. Лучше зарегистрировать их глобально, и сделать это так, чтобы потом мы просто делали базовый компонент, а дальше всё происходило само собой без нашего участия.

И сделать это совсем несложно. Информация ниже актуальна для приложения, созданного с помощью VUE-CLI, у которого под капотом используется webpack. Для начала нам нужно принять соглашение, что все базовые компоненты будут у нас начинаться с какого-то префикса. Допустим, _base-. Так у нас будут _base-button.vue, _base-input.vue и т.д. И мы будем глобально их регистрировать как BaseButton, BaseInput. Для автоматизации этого процесса создадим в папке, в которой хранятся компоненты (обычно это папка components) файл _globals.js. Для начала нам нужно найти все файлы, начинающиеся с _base-. И сделаем мы это с помощью доступной в webpack функции require.context():

const requiredComponents = require.context(
  // Смотрим только в текущей папке
  '.',
  // Не смотрим в дочерних папках
  false,
  // Выбираем только файлы с префиксом _base-
  /_base-[\w-]+\.vue$/
)

Дальше для каждого найденного файла нам нужно конвертировать название в PascalCalse:

requiredComponents.keys().forEach(name => {
  const componentConfig = requiredComponents(name);
  const componentName = name
    // Убираем "./_" из начала имени файла
    .replace(/^\.\/_/, '')
    // Убираем расширение файла
    .replace(/\.\w+$/, '')
    // Разбиваем на части
    .split('-')
    // Делаем заглавные буквы
    .map((kebab) => kebab.charAt(0).toUpperCase() + kebab.slice(1))
    // Объединяем всё
    .join('')
})

И теперь остаётся только зарегистрировать это всё глобально:

Vue.component(componentName, componentConfig.default || componentConfig)
});

В итоге файл _globals.js будет выглядеть вот так:

import Vue from Vue;

const requiredComponents = require.context(
  '.',
  false,
  /_base-[\w-]+\.vue$/
);

requiredComponents.keys().forEach(name => {
  const componentConfig = requiredComponents(name);
  const componentName = name
    .replace(/^\.\/_/, '')
    .replace(/\.\w+$/, '')
    .split('-')
    .map((kebab) => kebab.charAt(0).toUpperCase() + kebab.slice(1))
    .join('')
});

Vue.component(componentName, componentConfig.default || componentConfig)
});

Ну и для того, чтобы всё полетело, нужно в App.js добавить строчку:

import './components/_globals'

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