w3resource
Vue Tutorial

Component Registration

Knowledge of component basic is assumed for this tutorial. Components Names

When we want to register a component, it always will be given a name. For instance, in the global registration seen so far:

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

The first argument of the Vue.component is the component's name.

Place we intend to use a component may influence its name. whenever we are using a component directly in the DOM, it is strongly recommended that we follow the w3c rules for custom tag names (all-lowercase, must contain a hyphen). This will help us avoid conflict with current and future HTML elements.

Name Casing

There are two options for defining a components name:

With kebab-case

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

In this case you can only use <my-component-name> to reference the component.

With PascalCase

When we define a component in PaschalCase:

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

We can either use either <my-component-name> as in kebab-case or <MyComponentName> to reference the component. However only kebab-case names valid in the DOM directly.

Using the Vue.component to create components makes them globally registered, and we can use them in any Vue instance (new Vue) created after the registration:

JS

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

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

Local Registration

Global registration is not ideal in most cases. When using a build system like webpack, globally registering all the components means that even when we stop using a component, it could still be in our final build. This increases the amount of JavaScript the user has to download. In such cases you can define your components as plain JavaScript objects:

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

Then use a components option to define the component you will like to use:

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

For every property in the components object, the key will be the custom elements name, while the value will contain the options object for that component.

Local Registration in a Module System

It is highly recommended that you create a components directory with each component in its own file.

Then each of those components can be imported as need may arise before you register them in the new .vue or .js file:

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

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

There sometimes when our components are relatively generic, and possibly wrap single elements like a button or an input. And these could be base components that are frequently reused. Thus we could have a long list of base components that is included in many components:

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

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

And these might support only a little markup in a template:

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

Fortunately for us, if we are using Webpack (or Vue CLI 3+), we can use require.context which will globally register only these common base components in the entry file of our app (e.g js/app.js):

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

const requireComponent = require.context(
  // find relative path of the components folder
  './components',
  // look in subfolders
  false,
  // The regular expression used to match base component filenames is 
  /Base[A-Z]\w+\.(vue|js)$/
)

requireComponent.keys().forEach(fileName => {
  // Get the component config
  const componentConfig = requireComponent(fileName)

  // Get the PascalCase name of component
  const componentName = upperFirst(
    camelCase(
      // retrieve the file name regardless of folder depth
      fileName
        .split('/')
        .pop()
        .replace(/\.\w+$/, '')
    )
  )


  // Register the component globally
  Vue.component(
    componentName,
    // Look up the component options on `.default`, this will
    // exist if the component was exported with `export default`,
    // if not it will fall back to module's root.
    componentConfig.default || componentConfig
  )
})