什么是异步组件
在 Vue 3 中,异步组件指的是一种在需要时才加载和渲染的组件。这意味着组件不会在应用启动时立即加载,而是在真正需要显示该组件的时候,才会动态地从服务器或文件系统中加载它。这种机制可以有效减少初始包的大小,有助于减少应用的初始加载时间,提高加载速度和应用的性能。
defineAsyncComponent
defineAsyncComponent 是 Vue 3中用于定义异步组件的一个函数,它允许开发者以声明式的方式定义一个在需要时才加载的组件。这个函数是 Vue 官方提供的,它简化了异步组件的使用过程,并提供了丰富的配置选项。下面将详细介绍一下 defineAsyncComponent 函数:
函数签名
import { defineAsyncComponent } from 'vue'defineAsyncComponent({loader: () => import('./child.vue'),...options
})
- loader: 一个返回 Promise 的函数,这个 Promise 在解析时应该返回一个组件配置对象(通常是一个组件的选项对象或一个组件定义函数)。这个函数通常使用动态导入 import() 来实现。
- options: 一个可选的对象,包含了异步组件的配置选项
options 的配置选项
-
defineAsyncComponent 函数接受一个可选的配置对象,该对象可以包含以下属性:
-
loadingComponent: 当异步组件正在加载时显示的组件。默认情况下,如果没有提供,Vue 会显示一个默认的加载指示器。
-
errorComponent: 当异步组件加载失败时显示的组件。默认情况下,如果没有提供,Vue 会显示一个错误信息。
-
delay: 一个数字,表示在显示加载组件之前等待的时间(以毫秒为单位)。默认为 0,即立即显示加载组件。
-
timeout: 一个数字,表示异步组件加载的超时时间(以毫秒为单位)。如果超时,将触发错误处理。默认为 Infinity,即没有超时限制。
-
onError: 一个函数,当异步组件加载失败时调用。这个函数接收错误对象作为参数。
实际应用
父级组件 Home.vue
<template><div class="home"><button @click="show = !show">加载组件</button><child v-if="show" /></div>
</template><script setup>
import { ref, defineAsyncComponent } from 'vue';let show = ref(false)
let child = defineAsyncComponent({loader: () => import('./child.vue')
})
</script>
子组件 child.vue
<template><div>{{ content }}</div>
</template><script setup>
import {ref} from 'vue'
let content = ref('子组件')
</script>
父级组件中的写法,对于这种比较简单的子组件来说,如果和普通正常加载对比通常视觉效果上没多大差距,例如以下这种写法,不管v-if 中show 的值,初始为true还是false,页面都会预先加载好child.vue这个组件的资源
而上面的通过defineAsyncComponent异步加载的这种写法,是在实际渲染的时候才会去加载对应的资源,可以理解为 vue-router 中使用过的**路由懒加载**。
<template><div class="home"><button @click="show = !show">加载组件</button><child v-if="show" /></div>
</template><script setup>
import { ref, defineAsyncComponent } from 'vue';
import child from './child.vue';
let show = ref(false)
</script>
正常加载 | 异步加载 |
---|---|
![]() | ![]() |
Suspense
<Suspense> 是一个内置组件,用来在组件树中协调对异步依赖的处理。它让我们可以在组件树上层等待下层的多个嵌套异步依赖项解析完成,并可以在等待时渲染一个加载状态。
但要注意的是<Suspense> 是一项实验性功能。它不一定会最终成为稳定功能,并且在稳定之前相关 API 也可能会发生变化。
Suspense 允许定义一个等待异步组件加载的“占位符”,在异步组件加载完成之前,可以显示一个加载状态或者默认内容。
实际应用
Suspense 组件的实例,用于包裹异步组件,允许在组件加载期间显示备用内容。
Suspense有两个插槽:#default 和 #fallback
#default 用来显示要加载的组件,#fallback 则是在异步组件加载时显示的内容
<template><div class="home"><button @click="show = !show">加载组件</button><Suspense v-if="show"><template #default><!-- 这里的 AsyncComponent 是一个异步加载的组件 --><child /></template><template #fallback><!-- 在异步组件加载时显示的内容,例如一个加载指示器 --><div>Loading...</div></template></Suspense></div></template><script setup>import { ref, defineAsyncComponent } from 'vue';let show = ref(false)let child = defineAsyncComponent({loader: () => {return new Promise((resolve, reject) => {setTimeout(() => {resolve( import('./child.vue'))}, 2000);})},delay: 2000})</script>
为了模拟延迟加载的效果,defineAsyncComponent的loader参数返回一个Promise,并定时2s后再resolve,在加载期间会显示#fallback插槽中的 Loading…,加载完后渲染child组件
下面是效果图