vue3 异步组件
前端开发经常遇到异步的问题,请求函数,链接库,等,都有可能需要通过promise或者async await 来进行异步的一个封装。异步组件也由此诞生,我用settimeout来模拟一个vue3的异步组件
前言
前端开发经常遇到异步的问题,请求函数,链接库,等,都有可能需要通过promise或者async await 来进行异步的一个封装。
异步组件也由此诞生,我用settimeout来模拟一个vue3的异步组件
异步的子组件
<template>
<div>{{ someData }}</div>
</template>
<script lang="ts">
import { ref } from 'vue'
import { Data } from './types/index'
export default {
setup(props: Data) {
const someData = ref('dx')
return new Promise((resolve, reject) => {
setTimeout(() => {
return resolve({ someData })
}, 3000)
})
}
}
</script>
按照正常组件使用
<template>
<div class="about">
<h1>This is an about page</h1>
<Child />
</div>
</template>
<script lang="ts">
import Child from '@/components/template/Template.vue'
export default {
components: {
Child
}
}
</script>
页面会有警告,而且组件渲染也失败了,解析了警告的意思,是说这种异步组件需要一个Suspense来包裹一下

Suspense 是vue3新增的一个内置组件,专门用来处理异步组件的。
异步组件的正确使用方式
<template>
<div class="about">
<h1>This is an about page</h1>
<Suspense>
<template v-slot:default>
<Child />
</template>
<template v-slot:fallback>
<h3>请稍等</h3>
</template>
</Suspense>
<!-- <Child /> -->
</div>
</template>
<script lang="ts">
import { defineAsyncComponent } from 'vue'
// import Child from '@/components/template/Template.vue'
const Child = defineAsyncComponent(() => import('@/components/template/Template.vue'))
export default {
components: {
Child
}
}
</script>
Suspense的原理是通过插槽来实现的,一个default和一个fallback。
default里面放置异步组件,fallback里面就放置异步组件未渲染之前的一个样式
有人说vue3中setup不能是异步函数,上面的代码证明,setup可以是异步函数,他们可能不了解Suspense这个内置组件。
async await 的setup函数
<template>
<div>{{ someData }}</div>
</template>
<script lang="ts">
import { ref } from 'vue'
import { Data } from './types/index'
export default {
async setup(props: Data) {
const currentInstance: ComponentInternalInstance | null = getCurrentInstance()
const someData = ref('dx')
const result = await new Promise((resolve, reject) => {
setTimeout(() => {
return resolve({ someData })
}, 3000)
})
return result
}
}
</script>
父组件通过Suspense使用异步的子组件
<template>
<div class="about">
<h1>This is an about page</h1>
<Suspense>
<template v-slot:default>
<Child />
</template>
<template v-slot:fallback>
<h3>请稍等</h3>
</template>
</Suspense>
<!-- <Child /> -->
</div>
</template>
<script lang="ts">
import { defineAsyncComponent } from 'vue'
// import Child from '@/components/template/Template.vue'
const Child = defineAsyncComponent(() => import('@/components/template/Template.vue'))
export default {
components: {
Child
}
}
</script>
最后总结一下,只要将异步组件放在suspense的default插槽中即可。
扩展阅读
在 Vue 3 中,异步组件的加载方式与 Vue 2 有一些不同。Vue 3 引入了 Suspense 特性,使异步组件的加载和处理更为灵活和直观。以下是如何在 Vue 3 中使用异步组件:
-
使用
defineAsyncComponent函数:Vue 3 提供了一个函数
defineAsyncComponent,用于定义异步加载的组件。你可以使用这个函数来创建一个异步组件,然后在需要的地方加载它。<template> <div> <button @click="loadComponent">Load Component</button> <Suspense> <AsyncComponent v-if="isComponentLoaded" /> <template #fallback>Loading...</template> </Suspense> </div> </template> <script> import { defineAsyncComponent, ref } from 'vue'; const AsyncComponent = defineAsyncComponent(() => import('./AsyncComponent.vue') ); export default { components: { AsyncComponent, }, setup() { const isComponentLoaded = ref(false); const loadComponent = () => { isComponentLoaded.value = true; }; return { isComponentLoaded, loadComponent }; }, }; </script>在上面的代码中,我们使用
defineAsyncComponent创建了一个异步组件,并在按钮点击时加载它。Suspense组件用于处理异步加载时的状态,<template #fallback>标签中的内容会在组件加载期间显示。 -
使用
defineAsyncComponent的工厂函数形式:你也可以使用工厂函数形式的
defineAsyncComponent来动态指定要加载的组件,这对于根据条件加载不同的组件很有用。<template> <div> <button @click="loadComponentA">Load Component A</button> <button @click="loadComponentB">Load Component B</button> <Suspense> <DynamicAsyncComponent v-if="isComponentLoaded" /> <template #fallback>Loading...</template> </Suspense> </div> </template> <script> import { defineAsyncComponent, ref } from 'vue'; const DynamicAsyncComponent = defineAsyncComponent(() => import(/* webpackChunkName: "dynamic-async" */ `./DynamicAsyncComponent.vue`) ); export default { components: { DynamicAsyncComponent, }, setup() { const isComponentLoaded = ref(false); const loadComponentA = () => { DynamicAsyncComponent.resolveComponent(() => import(`./ComponentA.vue`) ); isComponentLoaded.value = true; }; const loadComponentB = () => { DynamicAsyncComponent.resolveComponent(() => import(`./ComponentB.vue`) ); isComponentLoaded.value = true; }; return { isComponentLoaded, loadComponentA, loadComponentB }; }, }; </script>
在这个示例中,我们创建了一个名为 DynamicAsyncComponent 的异步组件,并使用 DynamicAsyncComponent.resolveComponent 方法动态指定要加载的组件。
异步组件的加载和管理在 Vue 3 中更为直观和灵活,可以更好地处理动态加载和懒加载组件的需求。

更多推荐


所有评论(0)