defineAsyncComponent en Vue 3: Implementación y casos de uso.

En Vue 3, la función defineAsyncComponent permite cargar componentes de manera asíncrona, lo que es útil para dividir aplicaciones grandes en partes más pequeñas y mejorar el rendimiento al cargar solo los componentes necesarios cuando se requieren.

split js files with defineAsyncComponent

Uso Básico:

Para definir un componente asíncrono, se utiliza defineAsyncComponent junto con una función que retorna una promesa. Generalmente, se emplea la función de importación dinámica para cargar el componente:

<script setup lang="ts">
  import { defineAsyncComponent } from 'vue'

  const AsyncComponent = defineAsyncComponent(() =>
    import('@/components/AsyncComponent.vue')
  )
</script>

En este ejemplo, AsyncComponent se cargará solo cuando sea necesario, reduciendo el tamaño inicial del paquete de la aplicación.

Manejo de Estados de Carga y Error:

defineAsyncComponent también permite manejar estados de carga y error mediante una configuración adicional:

<script setup lang="ts">
  import { defineAsyncComponent, ref } from 'vue'
  import LoadingComponent from '@/components/LoadingComponent.vue'
  import ErrorComponent from '@/components/ErrorComponent.vue'

  const AsyncComponent = defineAsyncComponent({
    loader: () => import('@/components/AsyncComponent.vue'),
    loadingComponent: LoadingComponent,
    errorComponent: ErrorComponent,
    delay: 200, // 200ms default
    timeout: 3000, // Infinity default
  })
</script>
  • loader: Función que retorna la promesa del componente a cargar.

  • loadingComponent: Componente que se muestra mientras el componente asíncrono se está cargando.

  • errorComponent: Componente que se muestra si ocurre un error durante la carga.

  • delay: Tiempo en milisegundos antes de mostrar el componente de carga.

  • timeout: Tiempo máximo en milisegundos para intentar cargar el componente antes de mostrar el componente de error.

Casos de Uso:

  1. Carga bajo demanda: Cargar componentes solo cuando el usuario los necesita, como en rutas específicas o modales, mejorando el rendimiento inicial de la aplicación.

  2. División de código: Dividir la aplicación en fragmentos más pequeños que se cargan según sea necesario, lo que reduce el tamaño del paquete inicial y mejora los tiempos de carga.

  3. Manejo de componentes pesados: Cargar componentes que dependen de bibliotecas grandes o que tienen un impacto significativo en el rendimiento solo cuando son necesarios.

Ejemplo completo:

<script setup lang="ts">
  import { defineAsyncComponent, ref } from 'vue'
  import LoadingComponent from '@/components/LoadingComponent.vue'
  import ErrorComponent from '@/components/ErrorComponent.vue'

  const showAsyncComponent = ref(false)

  const AsyncComponent = defineAsyncComponent({
    loader: () => import('@/components/AsyncComponent.vue'),
    loadingComponent: LoadingComponent,
    errorComponent: ErrorComponent,
    delay: 200, // 200ms default
    timeout: 3000, // Infinity default
  })
</script>

<template>
  <main>
    <div class="flex items-center justify-center mb-4">
      <button
        @click="showAsyncComponent = !showAsyncComponent"
        class="px-4 py-2 cursor-pointer bg-blue-500 text-white font-semibold rounded-lg shadow-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-400 focus:ring-opacity-75"
      >
        Cargar componente async
      </button>
    </div>

    <AsyncComponent v-if="showAsyncComponent" />
  </main>
</template>

Conclusión:

defineAsyncComponent es una herramienta poderosa en Vue 3 para optimizar aplicaciones grandes, permitiendo una carga más eficiente de componentes y mejorando la experiencia del usuario al reducir los tiempos de carga iniciales.

Ejemplo de carga asíncrona de componentes en Vue.js usando defineAsyncComponent, mostrando un componente en estado de carga con un spinner y código JavaScript para importar dinámicamente componentes.