Appearance
异步组件
在大型项目开发中,每个完整的页面都是由无数个小组件构成的。根据轻重缓急的渲染策略,我们可以优先渲染那些主要的组件,而非主要的组件可以延迟渲染,并仅在需要时再加载相关的组件。
defineAsyncComponent
为了能够加载异步组件,Vue 提供了 defineAsyncComponent
函数来实现此功能:
js
import { defineAsyncComponent } from 'vue'
// 1. 定义一个异步组件,命名为 AsyncComp
// defineAsyncComponent(fn) 的入参是一个“返回 Promise 的加载函数”
const AsyncComp = defineAsyncComponent(() => {
return new Promise((resolve, reject) => {
// 2. 从服务器获取组件
// 3. 如果组件获取成功,则调用 resolve() 并传入获取到的组件
resolve(/* 获取到的组件 */)
// 4. 如果获取失败,则调用 reject() 并传入失败的原因
// reject(reason)
})
})
// ... 像使用其他一般组件一样使用 `AsyncComp`
从本地加载异步组件
除了可以从服务器加载异步组件,我们还可以结合 defineAsyncComponent
+ ES 模块动态导入
的方式,从本地加载异步组件:
js
import { defineAsyncComponent } from 'vue'
// 异步加载本地的 SFC 组件
const AsyncComp = defineAsyncComponent(() => import('./components/MyComponent.vue'))
与普通组件一样,异步组件可以使用 app.component()
进行全局注册:
js
// 全局注册异步加载的本地组件
app.component(
'MyComponent',
defineAsyncComponent(() => import('./components/MyComponent.vue'))
)
或是直接在父组件中定义并使用它们:
vue
<script setup>
import { defineAsyncComponent } from 'vue'
// 局部导入异步加载的本地组件
const AdminPage = defineAsyncComponent(() => import('./components/AdminPageComponent.vue'))
</script>
<template>
<!-- 并直接使用 -->
<AdminPage />
</template>
加载与错误状态
异步组件难免会产生加载慢或超时的情况,为了提高用户的体验,defineAsyncComponent()
也支持提供 loading 提示和 timeout 超时处理。语法格式如下:
js
const AsyncComp = defineAsyncComponent({
// 加载函数
loader: () => import('需要异步加载的本地的 SFC 组件路径'),
// 加载异步组件时使用的组件
loadingComponent: LoadingComponent,
// 展示加载组件前的延迟时间,默认为 200ms
delay: 200,
// 加载失败后展示的组件
errorComponent: ErrorComponent,
// 如果提供了一个 timeout 时间限制,并超时了
// 也会显示这里配置的报错组件,默认值是:Infinity
timeout: 3000
})
示例代码如下:
vue
<script setup>
import { ref, defineAsyncComponent } from 'vue'
// 展示 loading 提示的组件
import Loading from './components3/Loading.vue'
// 超时之后,需要展示的错误组件
import ErrorPage from './components3/ErrorPage.vue'
// 使用 flag 布尔值,控制是否展示异步组件(这是为了方便调试)
// 刷新网页时不节流,点击按钮前,把网速调成 3G,方便演示异步组件加载慢的情况
const flag = ref(false)
const AdminPage = defineAsyncComponent({
// 通过 loader 属性指定要一步加载的组件
loader: () => import('./components3/AdminPageComponent.vue'),
// 指定 loading 提示组件
loadingComponent: Loading,
// 展示 loading 提示组件之前的延迟时间(ms),防止闪烁
delay: 200,
// 超时时长:最大等待时长(ms)
timeout: 1000,
// 超时之后,显示错误组件
errorComponent: ErrorPage
})
</script>
<template>
<button @click="flag = !flag">toggle</button>
<AdminPage v-if="flag" />
</template>