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/dynamic-async-components.md.

Working with dynamic components and asynchronous module loading in Vue 2.7.

Dynamic & Async Components

Dynamic component: đổi component hiển thị tại runtime. Async component: tải code component khi cần (lazy load) để giảm kích thước bundle ban đầu.

Dynamic component

Dùng <component :is="..."> để render component theo biến. Giá trị is là tên component đã đăng ký hoặc object component.

<template>
  <div>
    <button @click="current = 'tab-home'">Home</button>
    <button @click="current = 'tab-posts'">Posts</button>

    <component :is="current"></component>
  </div>
</template>

<script>
import TabHome from './TabHome.vue'
import TabPosts from './TabPosts.vue'

export default {
  components: { TabHome, TabPosts },
  data() {
    return { current: 'tab-home' }
  }
}
</script>

Dùng cho tab, wizard, render component theo dữ liệu (vd type của item quyết định component hiển thị).

keep-alive

Mặc định, đổi component bằng :is sẽ huỷ component cũ và tạo lại khi quay lại, mất state. Bọc <keep-alive> để giữ instance trong bộ nhớ.

<keep-alive>
  <component :is="current"></component>
</keep-alive>

Giữ state (vd nội dung đã gõ trong tab) khi chuyển qua lại. Lúc này hook activated và deactivated chạy thay cho mounted/destroyed.

Async component

Khai báo component bằng function trả về dynamic import(). Webpack tách thành chunk riêng, chỉ tải khi component được render lần đầu.

export default {
  components: {
    HeavyChart: () => import('./HeavyChart.vue')
  }
}

Dạng đầy đủ với loading/error state:

const AsyncChart = () => ({
  component: import('./HeavyChart.vue'),
  loading: LoadingSpinner,
  error: ErrorBlock,
  delay: 200,    // chờ 200ms mới hiện loading
  timeout: 5000  // quá 5s coi như lỗi
})

Dùng cho component nặng hoặc ít khi hiển thị (modal, biểu đồ, editor) để trang load nhanh hơn.

So sánh

Kỹ thuậtMục đích
<component :is>Đổi component hiển thị tại runtime
<keep-alive>Giữ state component khi ẩn/hiện
Async componentLazy load, tách bundle, tải khi cần

Tips cho AEM

Lazy load giúp clientlib gọn hơn, quan trọng khi component Vue nặng không xuất hiện trên mọi trang.

new Vue({
  el: '#app',
  components: {
    // chỉ tải chunk khi product modal được render
    ProductModal: () => import('./components/ProductModal.vue')
  }
})

Lưu ý cấu hình Webpack trong ui.frontend phải bật code splitting (mặc định đã bật) và clientlib build phải gom được các chunk sinh ra. Kiểm tra output có nhiều file JS chunk thay vì một bundle lớn.