news 2026/8/9 22:15:19

Suspense 异步组件

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Suspense 异步组件

Suspense 异步组件 | 源码解析系列 5.8

一,引言

Suspense是Vue3新增的内置组件,用于处理异步组件的加载状态。它允许开发者优雅地处理异步组件的loading、error和ready状态,提供更好的用户体验。本文将深入解析Vue3中Suspense的实现原理,包括异步组件的识别、加载状态管理、fallback渲染等方面。

二、Suspense概述

2.1 什么是Suspense

Suspense是一个特殊的组件,它可以等待其嵌套的异步组件加载完成后,再渲染默认内容。

<template> <Suspense> <template #default> <AsyncComponent /> </template> <template #fallback> <LoadingSpinner /> </template> </Suspense> </template>

2.2 使用场景

Suspense主要用于以下场景:异步组件加载、网络请求等待、动态导入组件、异步setup函数。

三、异步组件

3.1 defineAsyncComponent

异步组件通过defineAsyncComponent定义。

import{defineAsyncComponent}from'vue'constAsyncComponent=defineAsyncComponent(()=>import('./AsyncComponent.vue'))

3.2 异步组件选项

defineAsyncComponent({loader:()=>import('./AsyncComponent.vue'),loadingComponent:LoadingComponent,errorComponent:ErrorComponent,delay:200,timeout:3000,retry:3})

3.3 async setup

setup可以是异步函数。

exportdefault{asyncsetup(){constdata=awaitfetchData()return{data}}}

四、Suspense实现

4.1 Suspense组件定义

// packages/runtime-core/src/components/Suspense.tsexportconstSuspense={__isSuspense:true,process(n1:SuspenseVNode,n2:SuspenseVNode,container:HostElement,anchor:HostNode|null,parentComponent:ComponentInternalInstance,parentSuspense:SuspenseBoundary|null,isSVG:boolean,optimized:boolean):void{// 处理Suspense挂载和更新}}

4.2 SuspenseVNode结构

// Suspense VNodeinterfaceSuspenseVNode{type:typeofSuspense props:{timeout?:number}children:{default:VNode fallback:VNode}}

五、加载状态管理

5.1 Suspense状态

// Suspense内部状态interfaceSuspenseState{isLoading:booleanerror:Error|nullresolve:()=>voidpromise:Promise<void>|null}

5.2 状态转换

// 状态转换// pending -> resolved -> pending// -> rejected

六、异步依赖处理

6.1 依赖收集

Suspense收集所有异步依赖。

// 收集异步依赖functionresolveAsyncDependencies(comp:Component,parent:ComponentInternalInstance):Promise<any>{constpromises:Promise<any>[]=[]// 收集异步组件collectAsyncComponents(comp,promises)// 等待所有异步依赖returnPromise.all(promises)}

6.2 Promise处理

// 处理PromisefunctionsetupSuspense(comp:Component,parent:ComponentInternalInstance):SuspenseState{conststate:SuspenseState={isLoading:true,error:null,resolve:null,promise:null}state.promise=newPromise((resolve)=>{state.resolve=resolve})// 执行setup或加载异步组件execWithSuspense(comp,parent,state)returnstate}

七、fallback渲染

7.1 fallback内容

fallback在异步内容加载时显示。

// 渲染fallbackfunctionrenderFallbackContent(suspense:SuspenseState):VNode{if(suspense.isLoading){// 渲染fallbackreturnsuspense.fallbackVNode}}

7.2 切换时机

// 切换到默认内容functionresolveSuspense(suspense:SuspenseState):void{suspense.isLoading=falseif(suspense.resolve){suspense.resolve()}}

八、错误处理

8.1 错误边界

// 错误处理functionhandleAsyncError(error:Error,suspense:SuspenseState):void{suspense.isLoading=falsesuspense.error=errorif(suspense.reject){suspense.reject(error)}}

8.2 errorComponent

可以使用errorComponent显示错误状态。

// errorComponent处理defineAsyncComponent({loader:()=>import('./Async.vue'),errorComponent:ErrorComponent})

九、使用示例

9.1 基础用法

<template> <Suspense> <template #default> <AsyncComponent /> </template> <template #fallback> <LoadingSpinner /> </template> </Suspense> </template>

9.2 多个异步组件

<template> <Suspense> <template #default> <div> <AsyncComponent1 /> <AsyncComponent2 /> </div> </template> <template #fallback> <Loading /> </template> </Suspense> </template>

9.3 async setup

exportdefault{asyncsetup(){constuser=awaitfetchUser()return{user}}}

十、嵌套Suspense

10.1 多层Suspense

Suspense可以嵌套使用。

<Suspense> <template #default> <ParentAsync /> </template> <template #fallback> <Loading /> </template> </Suspense> <!-- ParentAsync内部 --> <Suspense> <template #default> <ChildAsync /> </template> <template #fallback> <ChildLoading /> </template> </Suspense>

十一、总结

本文深入解析了Vue3中Suspense异步组件的实现原理。Suspense通过收集异步依赖、管理加载状态、渲染fallback内容等机制,优雅地处理了异步组件的加载过程。它可以与defineAsyncComponent和async setup配合使用,提供更好的异步编程体验。


参考资料

  • Vue3 官方源码:https://github.com/vuejs/core
  • Vue3 Suspense:packages/runtime-core/src/components/Suspense.ts
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/9 22:14:03

【C++ STL】适配器简单介绍

适配器 适配器&#xff08;Adapter&#xff09;本质上是一种“包装器”&#xff0c;它对已有的容器&#xff08;vector、list、deque&#xff09;或迭代器、函数对象进行封装&#xff0c;改变其接口形式&#xff0c;以用来满足特定场景的使用需求。 特点&#xff1a; 依赖底层容…

作者头像 李华
网站建设 2026/7/14 15:31:51

PX4 调参与日志分析(基于 PX4 v1.13~v1.16 的工程实践)

版本声明本文内容基于 PX4 Autopilot 当前主线参数体系整理&#xff0c;适用于 PX4 v1.13&#xff5e;v1.16需要注意的是&#xff1a;旧版&#xff08;v1.11 / v1.12&#xff09;中部分参数仍保留 _ACC 后缀部分日志 topic 在新版本中已迁移到新的 uORB 命名体系启用 Control A…

作者头像 李华
网站建设 2026/7/14 15:31:52

项目中用了Spring的这11个高端用法,项目经理狂点赞

1.自定义拦截器 spring mvc拦截器根spring拦截器相比&#xff0c;它里面能够获取HttpServletRequest和HttpServletResponse等web对象实例。 spring mvc拦截器的顶层接口是&#xff1a;HandlerInterceptor&#xff0c;包含三个方法&#xff1a; preHandle 目标方法执行前执行…

作者头像 李华
网站建设 2026/7/14 15:31:53

【ABAP】ALV 指定单元格染色

在 ALV GRID 中可以修改想强调的单元格染色。但是这相比强调行染色功能更注重系统资源&#xff0c;因此注重速度的程序中要考虑一下是否使用此功能。在 ALV 报表开发中&#xff0c;为关键数据单元格设置醒目的颜色标识&#xff08;如异常数值标红&#xff09;&#xff0c;能大幅…

作者头像 李华