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, and this page is available as Markdown at https://nhanbe.id.vn/frontend/vue2.7/component-in-depth/components-basics.md.

Fundamentals of Vue 2.7 component hierarchy, props, and data flow.

Components Basics

Component là instance Vue tái sử dụng, có template, logic và style riêng. Trong AEM, mỗi AEM component thường mount một root Vue component, root đó chia nhỏ thành các child component thuần frontend.

Định nghĩa component

Component nhận gần như mọi option của instance (data, computed, methods, watch, lifecycle hooks), trừ vài option chỉ dành cho root như el.

Vue.component('button-counter', {
  data() {
    return { count: 0 }
  },
  template: '<button @click="count++">Clicked {{ count }} times</button>'
})

Trong dự án thực tế dùng Single File Component (.vue) thay cho template string:

<template>
  <button @click="count++">Clicked {{ count }} times</button>
</template>

<script>
export default {
  name: 'ButtonCounter',
  data() {
    return { count: 0 }
  }
}
</script>

data của component phải là function

Component dùng lại nhiều lần. Nếu data là object dùng chung, mọi instance sẽ share cùng state. data phải là function trả về object mới để mỗi instance có state độc lập.

// ĐÚNG: mỗi instance một object riêng
data() {
  return { count: 0 }
}

// SAI: mọi instance share chung
data: { count: 0 }

Tái sử dụng và tổ chức cây component

Mỗi lần dùng component là một instance độc lập:

<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>

Ứng dụng tổ chức thành cây: root chứa các component con, con lại chứa con của nó.

Luồng dữ liệu một chiều

Cha truyền xuống con qua props. Con báo ngược lên cha qua events. Con không sửa trực tiếp dữ liệu của cha.

Chi tiết ở các note Props và Custom Events.

name option

name giúp ích cho debug (hiện trong Vue Devtools), cho phép component tự gọi đệ quy, và dùng với <keep-alive>. Luôn đặt name cho SFC.

Tips cho AEM

Root component mount vào DOM HTL render. Các child component nằm gọn trong cây Vue, AEM không cần biết tới chúng.

import Vue from 'vue'
import ProductList from './components/ProductList.vue'

const el = document.getElementById('product-list')
if (el) {
  new Vue({
    render: h => h(ProductList, {
      props: { items: JSON.parse(el.dataset.items || '[]') }
    })
  }).$mount(el)
}

ProductList bên trong tự render nhiều ProductCard mà không cần thêm mount point hay dialog riêng. Chỉ tạo AEM component riêng khi author cần cấu hình độc lập.