Component registration
This page assumes that you have read Component Basics. If you don’t know much about components yet, I recommend you read it first.
Directory
Component name
When registering a component, we always need to give it a name. For example, we have seen during global registration:
Vue.component('my-component-name', { /* ... */ })The component name is the first parameter of
Vue.component.
single-file component), we strongly recommend following the W3C specification for custom component names (all letters lowercase and must contain a hyphen). This will help you avoid conflicts with current and future HTML elements.
You can find other suggestions on component names in theStyle Guide.
Component name case
There are two ways to define component names:Using kebab-case
Vue.component('my-component-name', { /* ... */ })When using kebab-case (dash separated names) to define a component, you must also use kebab-case when referencing the custom element , for example
<my-component-name>.
Using PascalCase
Vue.component('MyComponentName', { /* ... */ })When defining a component using PascalCase (named with the first letter capitalized), you can use either nomenclature when referencing the custom element. . In other words,
<my-component-name> and
<MyComponentName> are both acceptable. Note, however, that only kebab-case is valid when used directly in the DOM (i.e. non-string templates).
Global registration
So far, we have only used Vue.component
to create components:
Vue.component('my-component-name', { // ... 选项 ... })
These components are globally registered. That is to say, they can be used in the template of any newly created Vue root instance (new Vue
) after registration. For example:
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>
The same is true for all sub-components, which means that these three components can also use each other internally.
Local registration
Global registration is often not ideal. For example, if you use a build system like webpack, registering all components globally means that even if you no longer use a component, it will still be included in your final build result. This results in an unnecessary increase in the amount of JavaScript downloaded by users.
In these cases, you can define the component via a plain JavaScript object:
var ComponentA = { /* ... */ } var ComponentB = { /* ... */ } var ComponentC = { /* ... */ }
Then define the component you want to use in the components
option:
new Vue({ el: '#app', components: { 'component-a': ComponentA, 'component-b': ComponentB } })
For each attribute in the components
object, its attribute name is the name of the custom element, and its attribute value is the option object of this component.
Note: Partially registered components are not available in their child components. For example, if you want ComponentA
to be available in ComponentB
, you need to write:
var ComponentA = { /* ... */ } var ComponentB = { components: { 'component-a': ComponentA }, // ... }
Or if you are using ES2015 modules via Babel and webpack, then the code looks like It looks more like:
import ComponentA from './ComponentA.vue' export default { components: { ComponentA }, // ... }
Note that in ES2015, putting a variable name like ComponentA
in the object is actually the abbreviation of ComponentA: ComponentA
, which is the variable name Also:
The name of the custom element used in the template
The variable name that contains the options for this component
Module system
##If you fail
import /
require Use a module system, maybe skip this chapter for now. If you use it, we will provide you with some special instructions and precautions.
Local registration in the module system
If you are still reading, it means you Used module systems such as Babel and webpack. In these cases, we recommend creating acomponents directory and placing each component in its own file.
ComponentB.js or
ComponentB.vue file:
import ComponentA from './ComponentA' import ComponentC from './ComponentC' export default { components: { ComponentA, ComponentC }, // ... }Now
ComponentA and
ComponentC can be used in the template of
ComponentB.
Automated global registration of basic components
Maybe many of your components just wrap elements such as input boxes or buttons, which are relatively common. We sometimes call them basic components, and they are frequently used in various components.
So many components will have a long list containing basic components:
import BaseButton from './BaseButton.vue' import BaseIcon from './BaseIcon.vue' import BaseInput from './BaseInput.vue' export default { components: { BaseButton, BaseIcon, BaseInput } }
But it is only used for a small part of the template:
<BaseInput v-model="searchText" @keydown.enter="search" /> <BaseButton @click="search"> <BaseIcon name="search"/> </BaseButton>
Fortunately, if you If you use webpack (or Vue CLI 3 that uses webpack internally), you can use require.context
to globally register only these very common basic components. Here is a sample code that allows you to globally import basic components in the application entry file (such as 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 .split('/') .pop() .replace(/\.\w+$/, '') ) ) // 全局注册组件 Vue.component( componentName, // 如果这个组件选项是通过 `export default` 导出的, // 那么就会优先使用 `.default`, // 否则回退到使用模块的根。 componentConfig.default || componentConfig ) })
RememberThe behavior of global registration must Occurs before the root Vue instance (via new Vue) is created. HereThere is an example in a real project scenario.