> For AI agents: the complete documentation index is available at https://nhanbe.id.vn/llms.txt, the full documentation bundle is available at https://nhanbe.id.vn/llms-full.txt.

# Component Registration

Component phải được đăng ký trước khi dùng trong template. Có hai cách: global và local.

## Global registration

`Vue.component(name, options)` đăng ký component dùng được trong mọi component sau đó (phải gọi trước `new Vue`).

```js
Vue.component('base-button', {
  template: '<button class="btn"><slot /></button>'
})
```

Nhược điểm: component global luôn nằm trong build kể cả khi không dùng (không tree-shake được). Dùng cho số ít base component thật sự xuất hiện khắp nơi.

## Local registration

Import và khai báo trong option `components` của component cần dùng. Đây là cách mặc định nên dùng.

```vue
<script>
import BaseButton from './BaseButton.vue'

export default {
  components: {
    BaseButton
  }
}
</script>
```

Component đăng ký local chỉ dùng được trong chính component đó, không tự động có ở component con.

## So sánh

| Tiêu chí     | Global                       | Local                           |
| ------------ | ---------------------------- | ------------------------------- |
| Phạm vi      | Mọi component                | Chỉ component khai báo          |
| Tree-shaking | Không                        | Có                              |
| Khai báo     | `Vue.component()` một lần    | `components: {}` mỗi nơi dùng   |
| Dùng khi     | Base component dùng khắp nơi | Mặc định cho phần lớn component |

## Quy ước đặt tên

Hai kiểu đặt tên component:

- kebab-case: `<my-component>`. Bắt buộc khi viết trong DOM template (HTML không phân biệt hoa thường).
- PascalCase: `<MyComponent>`. Dùng được trong SFC/string template, Vue tự nhận cả hai dạng.

```js
components: {
  // tên PascalCase
  MyComponent
}
```

```html
<!-- trong SFC dùng được cả hai -->
<MyComponent />
<my-component />
```

Trong AEM, template HTL không hiểu custom tag. Custom tag chỉ hợp lệ bên trong SFC sau khi Webpack compile.

## Tips cho AEM

Tạo một registry map các root component (mount point) để bootstrapper tìm và mount. Chỉ root component cần có trong registry, child component được import cục bộ trong cha.

```js
import Hero from './components/Hero.vue'
import ProductList from './components/ProductList.vue'

const registry = {
  hero: Hero,
  'product-list': ProductList
}

document.querySelectorAll('[data-vue-component]').forEach(el => {
  const Component = registry[el.getAttribute('data-vue-component')]
  if (!Component) return
  new Vue({ render: h => h(Component) }).$mount(el)
})
```

Base component dùng nhiều nơi (button, icon) có thể đăng ký global một lần trong `main.js`. Component nghiệp vụ thì local.
