Skip to content

Async Components

Sử Dụng Cơ Bản

Trong các ứng dụng lớn, chúng ta có thể cần chia ứng dụng thành các phần nhỏ hơn và chỉ tải một thành phần từ máy chủ khi nó cần thiết. Để làm cho điều này trở nên khả thi, Vue có một hàm defineAsyncComponent:

js
import { defineAsyncComponent } from 'vue'

const AsyncComp = defineAsyncComponent(() => {
  return new Promise((resolve, reject) => {
    // ...tải thành phần từ máy chủ
    resolve(/* thành phần đã tải */)
  })
})
// ... sử dụng `AsyncComp` như một thành phần bình thường

Như bạn có thể thấy, defineAsyncComponent chấp nhận một hàm tải mà trả về một Promise. Callback resolve của Promise nên được gọi khi bạn đã nhận được định nghĩa thành phần từ máy chủ. Bạn cũng có thể gọi reject(reason) để báo hiệu rằng việc tải đã thất bại.

Import động ES module cũng trả về một Promise, vì vậy hầu hết thời gian chúng ta sẽ sử dụng nó kết hợp với defineAsyncComponent. Các công cụ đóng gói như Vite và webpack cũng hỗ trợ cú pháp này (và sẽ sử dụng nó làm điểm chia nhóm), cho phép chúng ta sử dụng nó để nhập các SFC Vue:

js
import { defineAsyncComponent } from 'vue'

const AsyncComp = defineAsyncComponent(() =>
  import('./components/MyComponent.vue')
)

Kết quả AsyncComp là một thành phần bọc chỉ gọi hàm tải khi thực sự được vẽ trên trang. Ngoài ra, nó sẽ chuyển tiếp bất kỳ props và slots nào đến thành phần bên trong, cho phép bạn sử dụng bọc bất đồng bộ để thay thế một cách mượt mà cho thành phần gốc trong khi đạt được việc tải lười biếng.

Tương tự như các thành phần bình thường, các thành phần bất đồng bộ có thể đăng ký toàn cầu bằng cách sử dụng app.component():

js
app.component(
  'MyComponent',
  defineAsyncComponent(() => import('./components/MyComponent.vue'))
)

Bạn cũng có thể sử dụng defineAsyncComponent khi đăng ký một thành phần cục bộ:

vue
<script>
import { defineAsyncComponent } from 'vue'

export default {
  components: {
    AdminPage: defineAsyncComponent(() =>
      import('./components/AdminPageComponent.vue')
    )
  }
}
</script>

<template>
  <AdminPage />
</template>

Chúng cũng có thể được định nghĩa trực tiếp bên trong thành phần cha của chúng:

vue
<script setup>
import { defineAsyncComponent } from 'vue'

const AdminPage = defineAsyncComponent(() =>
  import('./components/AdminPageComponent.vue')
)
</script>

<template>
  <AdminPage />
</template>

Trạng Thái Tải và Lỗi

Các hoạt động không đồng bộ không tránh khỏi trạng thái tải và lỗi - defineAsyncComponent() hỗ trợ xử lý các trạng thái này thông qua các tùy chọn nâng cao:

js
const AsyncComp = defineAsyncComponent({
  // hàm tải
  loader: () => import('./Foo.vue'),

  // Một thành phần để sử dụng trong khi thành phần không đồng bộ đang tải
  loadingComponent: LoadingComponent,
  // Độ trễ trước khi hiển thị thành phần tải. Mặc định: 200ms.
  delay: 200,

  // Một thành phần để sử dụng nếu quá trình tải thất bại
  errorComponent: ErrorComponent,
  // Thành phần lỗi sẽ được hiển thị nếu có một thời gian chờ được cung cấp và vượt quá. Mặc định: Infinity.
  timeout: 3000
})

Nếu có một thành phần tải được cung cấp, nó sẽ được hiển thị trước khi thành phần bên trong đang được tải. Có một độ trễ mặc định là 200ms trước khi thành phần tải được hiển thị - điều này là do trên các mạng nhanh, một trạng thái tải ngay lập tức có thể bị thay thế quá nhanh và kết quả có thể trông giống như một đèn nhấp nháy.

Nếu một thành phần lỗi được cung cấp, nó sẽ được hiển thị khi Promise trả về bởi hàm tải bị từ chối. Bạn cũng có thể chỉ định một thời gian chờ để hiển thị thành phần lỗi khi yêu cầu mất quá nhiều thời gian.

Sử Dụng với Suspense

Các thành phần không đồng bộ có thể được sử dụng với thành phần tích hợp <Suspense>. Tương tác giữa <Suspense> và các thành phần không đồng bộ được mô tả trong chương riêng về <Suspense>.

Async Components has loaded