Registro de Componentes

Esta página assume que você já leu o Básico sobre Componentes. Leia lá primeiro se você for novo com componentes.

Nome dos Componentes

Quando registramos um componente, sempre daremos um nome. Por exemplo, no registro global que vimos até agora:

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

O nome do componente é o primeiro argumento de Vue.component.

O nome que você dá a um componente depende de onde você pretende utilizá-lo. Quando for utilizar diretamente no DOM (ao contrário de uma template String ou um Componente Single-File, nós recomendamnos fortemente seguir as regras do W3C para nome de tags customizadas (todas as letras minuscúlas, com hifén entre as palavras). Isso lhe ajuda a evitar conflitos com atuais e futuros elementos nativos do HTML.

Você pode ver outras recomendações sobre nome de componentes no Guia de Estilo.

Convenção do Nome

Você tem duas opções quando estiver definindo nomes de componentes:

Com kebab-case

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

Quando definir um nome de componente com kebab-case, você precisa usar a mesma notação quando for referenciar como um elemento customizado, algo como <my-component-name>.

Com PascalCase

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

Quando definir um nome de componente com PascalCase, você pode usar ambas as notações quando referenciar esse elemento customizado. Isso significa que tanto <my-component-name> quanto <MyComponentName> serão aceitos. Note que, entretanto, apenas o nome em kebab-case é valido diretamente no DOM (ou seja, fora de templates baseados em Strings).

Registro Global

Até agora, apenas criamos componentes usando Vue.component:

Vue.component('my-component-name', {
// ... opções ...
})

Este componentes são registrados globalmente. Isso significa que eles podem ser usados em templates de qualquer instância Vue (new Vue) criada após o registro. Por exemplo:

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>

Isso também é aplicado para todos os subcomponentes, isso significa que todos estes três componentes também estão disponíveis dentro um do outro.

Registro Local

Registro global frequentemente não é ideal. Por exemplo, se você está usando um sistema de empacotamento com Webpack, registrar globalmente todos seus componentes significa que, mesmo se você parar de usar um componente, ele ainda estará incluído no seu build final. Isso aumenta desnecessariamente a quantidade de JavaScript que seu usuário precisará baixar.

Nesses casos, você pode definir seus componentes como simples objetos JavaScript:

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

Então, defina os componentes que você gostaria de usar com a opção components:

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

Para cada propriedade no objeto components, a chave será o nome do elemento customizado, enquanto o valor conterá o objeto de opções para o componente.

Note que registrar localmente os componentes não os torna disponíveis em subcomponentes. Por exemplo, se você quiser que o ComponentA esteja disponível dentro do ComponentB, você terá que usar:

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

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

Ou, se você usa módulos ES2015, através de Babel e Webpack, pode ficar mais parecido com:

import ComponentA from './ComponentA.vue'

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

Note que em ES2015+, colocar uma variável com nome ComponentA dentro de um objeto é um atalho para ComponentA: ComponentA, isto quer dizer que o nome da variável é ambos:

Sistema de Módulos

Se você não está usando um sistema de módulos com import/require, provavelmente pode pular esta seção agora. Se estiver usando, temos algumas instruções especiais e dicas para você.

Registro Local em um Sistema de Módulos

Se você continua aqui, então felizmente você está utilizando um sistema de módulos, tal como Babel e Webpack. Nesse caso, nós recomendamos criar um diretório components, com cada componente em seu próprio arquivo.

Então, importe cada componente se você desejar utilizá-lo, antes de registrar localmente. Por exemplo, em um hipotético arquivo ComponentB.js ou ComponentB.vue:

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

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

Agora, ambos ComponentA e ComponentC podem ser utilizados dentro do template do ComponentB.

Registro Global Automático para Componentes de Base

Muitos dos seus componentes vão ser relativamente genéricos, possivelmente apenas encapsulando um elemento como um input ou um button. Às vezes nos referimos a eles como componentes base e tendem a ser usados frequentemente entre vários de seus outros componentes.

O resultado é que muitos componentes podem incluir uma longa lista de componentes base:

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

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

Apenas para permitir uma marcação relativamente pequena no template:

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

Felizmente, se você estiver usando Webpack (ou Vue CLI 3+, que usa o Webpack internamente), você pode se aproveitar do require.context para registrar globalmente apenas os componentes base mais comuns. Aqui, um exemplo de código que permite a importação global de componentes base no arquivo de entrada de seu aplicativo (por exemplo, src/main.js):

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

const requireComponent = require.context(
// O caminho relativo da pasta de componentes
'./components',
// Se deve ou não olhar subpastas
false,
// Expressão regular para localizar nomes de componentes base
/Base[A-Z]\w+\.(vue|js)$/
)

requireComponent.keys().forEach(fileName => {
// Pega a configuração do componente
const componentConfig = requireComponent(fileName)

// Obtém nome em PascalCase do componente
const componentName = upperFirst(
camelCase(
// Tira o início `./` e a extensão do nome do arquivo
fileName.replace(/^\.\/(.*)\.\w+$/, '$1')
)
)

// Registra o componente globalmente
Vue.component(
componentName,
// Olha para as opções em `.default`, existentes
// se o componente foi exportado com `export default`,
// caso contrário usa o módulo raiz.
componentConfig.default || componentConfig
)
})

Lembre-se que o registro global precisa ocorrer antes da instância Vue ser criada (com new Vue). Veja um exemplo desse padrão em um contexto de projeto real.