Skip to content

Move component registration #42

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 29 commits into from
Jan 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
728e5a7
feat: started component basics
Jan 20, 2020
7c67b7d
feat: add button-counter example
Jan 20, 2020
89774c7
feat: moved component props
Jan 20, 2020
64847f5
feat: reworked events on components
Jan 20, 2020
b68d5db
Added v-model on components
Jan 21, 2020
ceb3aaa
feat: added slots to components basic
Jan 21, 2020
ee9757e
feat: added dynamic components
Jan 21, 2020
047ccfc
fix: fixed config
Jan 22, 2020
6f53955
fix: replaced fiddles with codesandboxes
Jan 22, 2020
22292da
Merge branch 'master' into move-component-basics
NataliaTepluhina Jan 22, 2020
72cf025
Merge branch 'master' into move-component-basics
NataliaTepluhina Jan 23, 2020
9e017f4
Update src/guide/component-basics.md
NataliaTepluhina Jan 25, 2020
bd6906c
fix: removed new Vue reminiscenses
Jan 25, 2020
7408763
Merge branch 'move-component-basics' of github.com:vuejs/docs-next in…
Jan 25, 2020
480d069
fix: fixed createApp reference
Jan 25, 2020
a0daafd
fix: fixed update events names
Jan 25, 2020
65fb43c
fix: fixed createApp
Jan 26, 2020
3d1d7f4
fix: changed modelValue to be camelCase
Jan 27, 2020
f03509a
fix: fixed prop name
Jan 27, 2020
caf4de5
Update src/guide/component-basics.md
NataliaTepluhina Jan 28, 2020
ba7519f
Update src/guide/component-basics.md
NataliaTepluhina Jan 28, 2020
ba6221d
feat: added a note on case-insensitiveness
Jan 28, 2020
dc085e5
feat: moved component registration
Jan 28, 2020
23d76af
Merge branch 'master' into move-component-registration
Jan 28, 2020
64a76e3
Update src/guide/component-registration.md
NataliaTepluhina Jan 29, 2020
28a0d99
Update src/guide/component-registration.md
NataliaTepluhina Jan 29, 2020
20a0324
Update src/guide/component-registration.md
NataliaTepluhina Jan 29, 2020
41284fe
fix: removed global base registration recipe
Jan 29, 2020
01c8c47
Merge branch 'move-component-registration' of github.com:vuejs/docs-n…
Jan 29, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,13 @@ module.exports = {
'list',
'events',
'forms',
'component-basics',
'component-basics'
]
},
{
title: 'Components In-Depth',
collapsable: true,
children: ['component-registration']
}
]
}
Expand Down
179 changes: 179 additions & 0 deletions src/guide/component-registration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
# Component Registration

> This page assumes you've already read the [Components Basics](component-basics.md). Read that first if you are new to components.

<div class="vueschool"><a href="https://vueschool.io/lessons/global-vs-local-components?friend=vuejs" target="_blank" rel="sponsored noopener" title="Free Vue.js Component Registration lesson">Watch a free video lesson on Vue School</a></div>

## Component Names

When registering a component, it will always be given a name. For example, in the global registration we've seen so far:

```js
const app = createApp({...})

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

The component's name is the first argument of `app.component`. In the example above, the component's name is "my-component-name".

The name you give a component may depend on where you intend to use it. When using a component directly in the DOM (as opposed to in a string template or [single-file component](TODO: single-file-components.html)), we strongly recommend following the [W3C rules](https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name) for custom tag names:

1. All lowercase
2. Contains a hyphen (i.e., has multiple words connected with the hyphen symbol)

By doing so, this will help you avoid conflicts with current and future HTML elements.

You can see other recommendations for component names in the [Style Guide](TODO:../style-guide/#Base-component-names-strongly-recommended).

### Name Casing

When defining components in a string template or a single-file component, you have two options when defining component names:

#### With kebab-case

```js
app.component('my-component-name', {
/* ... */
})
```

When defining a component with kebab-case, you must also use kebab-case when referencing its custom element, such as in `<my-component-name>`.

#### With PascalCase

```js
app.component('MyComponentName', {
/* ... */
})
```

When defining a component with PascalCase, you can use either case when referencing its custom element. That means both `<my-component-name>` and `<MyComponentName>` are acceptable. Note, however, that only kebab-case names are valid directly in the DOM (i.e. non-string templates).

## Global Registration

So far, we've only created components using `Vue.component`:

```js
Vue.createApp({...}).component('my-component-name', {
// ... options ...
})
```

These components are **globally registered**. That means they can be used in the template of any root Vue instance created after registration. For example:

```js
const app = Vue.createApp({})

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

app.mount('#app')
```

```html
<div id="app">
<component-a></component-a>
<component-b></component-b>
<component-c></component-c>
</div>
```

This even applies to all subcomponents, meaning all three of these components will also be available _inside each other_.

## Local Registration

Global registration often isn't ideal. For example, if you're using a build system like Webpack, globally registering all components means that even if you stop using a component, it could still be included in your final build. This unnecessarily increases the amount of JavaScript your users have to download.

In these cases, you can define your components as plain JavaScript objects:

```js
const ComponentA = {
/* ... */
}
const ComponentB = {
/* ... */
}
const ComponentC = {
/* ... */
}
```

Then define the components you'd like to use in a `components` option:

```js
const app = Vue.createApp({
components: {
'component-a': ComponentA,
'component-b': ComponentB
}
})
```

For each property in the `components` object, the key will be the name of the custom element, while the value will contain the options object for the component.

Note that **locally registered components are _not_ also available in subcomponents**. For example, if you wanted `ComponentA` to be available in `ComponentB`, you'd have to use:

```js
const ComponentA = {
/* ... */
}

const ComponentB = {
components: {
'component-a': ComponentA
}
// ...
}
```

Or if you're using ES2015 modules, such as through Babel and Webpack, that might look more like:

```js
import ComponentA from './ComponentA.vue'

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

Note that in ES2015+, placing a variable name like `ComponentA` inside an object is shorthand for `ComponentA: ComponentA`, meaning the name of the variable is both:

- the custom element name to use in the template, and
- the name of the variable containing the component options

## Module Systems

If you're not using a module system with `import`/`require`, you can probably skip this section for now. If you are, we have some special instructions and tips just for you.

### Local Registration in a Module System

If you're still here, then it's likely you're using a module system, such as with Babel and Webpack. In these cases, we recommend creating a `components` directory, with each component in its own file.

Then you'll need to import each component you'd like to use, before you locally register it. For example, in a hypothetical `ComponentB.js` or `ComponentB.vue` file:

```js
import ComponentA from './ComponentA'
import ComponentC from './ComponentC'

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

Now both `ComponentA` and `ComponentC` can be used inside `ComponentB`'s template.