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

Подразумевается, что вы уже изучили и разобрались с разделом Основы компонентов. Если нет — прочитайте его сначала.

Именование компонентов

При регистрации компонента у него всегда будет имя. Например, при глобальной регистрации, которую мы видели до сих пор:

Vue.component('my-component-name', { /* ... */ })

Именем компонента будет первый аргумент Vue.component.

Имя, которое вы даёте компоненту, может зависеть от того, где вы собираетесь его использовать. При использовании компонента непосредственно в DOM (в отличие от строковых шаблонов или однофайловых компонентов), мы настоятельно рекомендуем следовать правилам W3C для именования пользовательских тегов (все символы в нижнем регистре, должен содержать дефис). Это позволит избежать конфликтов с текущими и будущими HTML-элементами.

Вы можете изучить другие рекомендации по именованию компонентов в разделе Рекомендаций.

Стиль именования

У вас есть два способа указания имён компонентов:

В стиле kebab-case

Vue.component('my-component-name', { /* ... */ })

При определении компонента в стиле kebab-case, вы также должны использовать kebab-case при обращении к пользовательскому элементу, например так <my-component-name>.

В стиле PascalCase

Vue.component('MyComponentName', { /* ... */ })

При определении компонента в стиле PascalCase, вы можете использовать любой стиль именования при обращении к пользовательскому элементу. Это означает, что <my-component-name> и <MyComponentName> являются приемлемыми вариантами. Однако, обратите внимание, что только имена в kebab-case являются валидными при использовании непосредственно в DOM (т.е. не строковые шаблоны).

Глобальная регистрация

До сих пор мы создавали компоненты с помощью Vue.component:

Vue.component('my-component-name', {
// ... опции ...
})

Такие компоненты регистрируются глобально. Это означает, что они могут использоваться в шаблоне любого корневого экземпляра (new Vue), созданного после регистрации. Например:

Vue.component('component-a', { /* ... */ })
Vue.component('component-b', { /* ... */ })
Vue.component('component-c', { /* ... */ })

new Vue({ el: '#app' })
<div id="app">
<component-a></component-a>
<component-b></component-b>
<component-c></component-c>
</div>

Это относится также ко всем дочерним компонентам и означает что все три из этих компонентов также будут доступны внутри каждого из них.

Локальная регистрация

Глобальная регистрация часто не идеальна. Например, если вы используете систему сборки, такую как Webpack, глобальная регистрация всех компонентов означает, что даже если вы прекратите использовать компонент, то он всё равно будет включён в вашу сборку приложения. Это излишне увеличит количество JavaScript, который должны будут загрузить ваши пользователи.

В таких случаях вы можете определить свои компоненты как обычные объекты JavaScript:

var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
var ComponentC = { /* ... */ }

Затем укажите компоненты которые вы хотите использовать в опции components:

new Vue({
el: '#app',
components: {
'component-a': ComponentA,
'component-b': ComponentB
}
})

Для каждого свойства в объекте components, ключ будет именем пользовательского элемента, в то время как значение будет объектом, содержащим опции компонента.

Обратите внимание, что локально зарегистрированные компоненты не будут доступны в дочерних компонентах. Например, если вы хотите, чтобы ComponentA был доступен в ComponentB, вам нужно будет использовать:

var ComponentA = { /* ... */ }

var ComponentB = {
components: {
'component-a': ComponentA
},
// ...
}

Или если вы используете модули ES2015, например, через Babel и Webpack, это может выглядеть так:

import ComponentA from './ComponentA.vue'

export default {
components: {
ComponentA
},
// ...
}

Обратите внимание, что в ES2015+ указание имени переменной, такой как ComponentA внутри объекта, является сокращением для ComponentA: ComponentA, что означает имя переменной будет:

Модульные системы

Если вы не используете модульную систему с import/require, вы можете пропустить этот раздел сейчас. Если используете — у нас есть для вас специальные инструкции и советы.

Локальная регистрация в модульной системе

Если вы ещё здесь, вероятно вы используете модульную систему, такую как Babel и Webpack. В этих случаях мы рекомендуем создать каталог components, с каждым компонентом в его собственном файле.

Затем вам нужно будет импортировать каждый компонент, который вы хотите использовать, прежде чем регистрировать его локально. Например, в гипотетическом файле ComponentB.js или ComponentB.vue:

import ComponentA from './ComponentA'
import ComponentC from './ComponentC'

export default {
components: {
ComponentA,
ComponentC
},
// ...
}

Теперь оба компонента ComponentA и ComponentC могут быть использованы в шаблоне ComponentB.

Автоматическая глобальная регистрация базовых компонентов

Многие из ваших компонентов будут относительно общими, возможно только оборачивая элемент, например input или button. Мы иногда ссылаемся на них, как на базовые компоненты и они, как правило, очень часто используются в ваших компонентах.

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

import BaseButton from './BaseButton.vue'
import BaseIcon from './BaseIcon.vue'
import BaseInput from './BaseInput.vue'

export default {
components: {
BaseButton,
BaseIcon,
BaseInput
}
}

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

<BaseInput
v-model="searchText"
@keydown.enter="search"
/>
<BaseButton @click="search">
<BaseIcon name="search"/>
</BaseButton>

К счастью, если вы используете Webpack (или Vue CLI 3+, которая использует Webpack внутри), вы можете использовать require.context для глобальной регистрации только таких, очень общих базовых компонентов. Ниже приведён пример кода, который можно использовать для глобального импорта базовых компонентов в файле точки старта вашего приложения (например, src/main.js):

import Vue from 'vue'
import upperFirst from 'lodash/upperFirst'
import camelCase from 'lodash/camelCase'

const requireComponent = require.context(
// Относительный путь до каталога компонентов
'./components',
// Обрабатывать или нет подкаталоги
false,
// Регулярное выражение для определения файлов базовых компонентов
/Base[A-Z]\w+\.(vue|js)$/
)

requireComponent.keys().forEach(fileName => {
// Получение конфигурации компонента
const componentConfig = requireComponent(fileName)

// Получение имени компонента в PascalCase
const componentName = upperFirst(
camelCase(
// Удаление из начала `./` и расширения из имени файла
fileName.replace(/^\.\/(.*)\.\w+$/, '$1')
)
)

// Глобальная регистрация компонента
Vue.component(
componentName,
// Поиск опций компонента в `.default`, который будет существовать,
// если компонент экспортирован с помощью `export default`,
// иначе будет использован корневой уровень модуля.
componentConfig.default || componentConfig
)
})

Запомните, что глобальная регистрация должна происходить до создания корневого экземпляра Vue (с помощью new Vue). Вот пример этого шаблона в реальном контексте проекта.