当前位置: 首页 > news >正文

Vue与React的Suspense组件对比

在Vue和React中都内置了Suspense组件,该组件用于处理异步组件加载。当Suspense包裹的实际组件内容尚未加载完成时会先展示后备内容,等待组件内容加载完成后再切换成实际组件内容。这可以显著提升用户体验,适用于大数据加载、组件懒加载等场景。

Vue—Suspense

Vue中的<Suspense>组件有两个插槽:#default#fallback两个插槽都只允许一个直接子节点。在渲染时都将优先渲染默认插槽中的节点,如果遇到异步组件(使用defineAsyncComponent定义的组件)或者加载的组件带有异步setup钩子(如下代码)时(官方文档称作异步依赖),将显示后备插槽fallback中的节点(一般是用于加载过程中的占位内容,如加载动画或提示文字)。

export default {async setup() {}
}
// 或者
<script setup>const res = await getUser(); // setup顶层有await
</script>

加载状态

在初始渲染时,<Suspense> 将在内存中渲染其默认的插槽内容。如果在这个过程中遇到任何异步依赖,则会进入挂起状态。在挂起状态期间,展示的是后备内容。当所有遇到的异步依赖都完成后,<Suspense> 会进入完成状态,并将展示出默认插槽的内容。如果在初次渲染时没有遇到异步依赖,<Suspense> 会直接进入完成状态。

进入完成状态后,只有当默认插槽的根节点被替换时,<Suspense> 才会回到挂起状态。组件树中新的更深层次的异步依赖不会造成 <Suspense> 回退到挂起状态。

发生回退时,后备内容不会立即展示出来。相反,<Suspense> 在等待新内容和异步依赖完成时,会展示之前 #default 插槽的内容。这个行为可以通过一个 timeout prop 进行配置:在等待渲染新内容耗时超过 timeout 之后,<Suspense> 将会切换为展示后备内容。若 timeout 值为 0 将导致在替换默认内容时立即显示后备内容。

事件

事件名事件描述
pending当 <Suspense> 进入挂起状态时触发(异步操作开始),适合用来启动加载动画
resolve当 <Suspense> 内部所有异步操作完成并切换到正常内容时触发,适合用来停止加载动画或执行完成逻辑
fallback当 <Suspense> 渲染备用内容(#fallback 插槽)时触发,适合用来记录进入备用状态的日志或执行额外逻辑

事件的执行顺序:pending—>fallback—>resolve

<template><div><!-- 监听这三个事件记录当前状态 --><Suspense @pending="setStatus('Pending')" @resolve="setStatus('Resolved')" @fallback="setStatus('Fallback')"><template #default><AsyncComponent /></template><template #fallback><div>Loading fallback...</div></template></Suspense><p>Current Status: {{ status }}</p></div>
</template><script setup>
import { ref } from 'vue';
import { defineAsyncComponent } from 'vue';
const AsyncComponent = defineAsyncComponent(() =>new Promise((resolve) => {setTimeout(() => {resolve({ template: `<div>Async Component Content</div>` });}, 2000);})
);
const status = ref('');
const setStatus = (newStatus) => status.value = newStatus;
</script>

注意:如果 #default 中没有异步依赖,这些事件不会被触发。且pending 和 fallback 事件通常紧密关联,前者触发时后者也会触发。

嵌套使用

当一个Suspense组件下有多个异步依赖且它们之间互相独立时,由于都处在同一个Suspense边界下,即使其中一些已经加载完成也不会进行渲染,而是会等待所有异步依赖全部加载完成最终才会渲染,这样依赖总是同时加载,可能会影响用户的体验。因此,可以嵌套使用Suspense,即某部分依赖先加载完成后不必等待其它依赖加载完成即可渲染。
Vue中Suspense组件的参数
可以发现:Suspense的suspensible属性的默认值是false,且可以设置一个超时时间,当默认内容加载时间超时时即不会再加载默认内容而是渲染后备内容。另外,也可以监听该组件的pending、resolve和fallback事件。

<Suspense><template #default><div><AsyncComponentOuter /><Suspense suspensible> {/* 设置suspensible后所有异步依赖项处理都会交给父级 <Suspense> (包括发出的事件) */}<template #default><AsyncComponentInter /></template><template #fallback>内层加载中...</template></Suspense></div></template><template #fallback>外层加载中...</template>
</Suspense>

React—Suspense

React中主要语法如下:

<Suspense fallback={<Loading />}> {/* 这是suspense默认渲染的内容在加载完成之前渲染的后备内容 */}<Albums />  {/* 这是suspense默认渲染的内容 */}
</Suspense>

Suspense中同样支持嵌套使用,这样Suspense中的内容就可以逐步被渲染。通过合理嵌套 Suspense,就可以更早地显示部分页面内容,同时等待其他内容的加载,从而提高用户体验。

<Suspense fallback={<BigSpinner />}> {/* Biography的后备内容 */}<Biography /><Suspense fallback={<AlbumsGlimmer />}> {/* Panel的后备内容 */}<Panel><Albums /></Panel></Suspense>
</Suspense>

配合lazy组件使用:

import { lazy, Suspense } from "react";
const LazyComponent = lazy(() => import("./LazyComponent")); // 懒加载该组件
export default function App() {return (<div><h1>React Suspense Example</h1>{/* Suspense 组件包裹 LazyComponent */}<Suspense fallback={<div>Loading...</div>}><LazyComponent /></Suspense></div>);
}

React中的Suspense也可以结合useTransitionuseDeferredValue等hooks一起使用来控制后备内容的显示与隐藏。

Suspense在Vue和React中对比

  • Vue中该组件有默认插槽和fallback插槽,这两个插槽的内容都不支持多根节点;而React中的默认插槽可以支持多个根节点。
  • Vue中Suspense组件可以处理任意的异步逻辑(不仅限于组件,如数据请求),而React默认只支持组件级的懒加载,需要和其他库(如 React Query 或 Relay)集成来支持更复杂的数据加载。
  • 另外,在SSR结合Suspense使用上可能存在一定的差异。

参考:1、React内置组件—Suspense
           2、Vue内置组件—Suspense

http://www.lryc.cn/news/490110.html

相关文章:

  • Spring框架深度剖析:特性、安全与优化
  • 硬盘文件误删:全面解析、恢复方案与预防策略
  • tcpdump抓包 wireShark
  • Android system_server进程
  • Vue3+element-plus 实现中英文切换(Vue-i18n组件的使用)
  • python实现猜数字游戏( 可视化easygui窗口版本 )
  • 自由学习记录(23)
  • Java语言程序设计 选填题知识点总结
  • 鸿蒙生态:开发者的新蓝海与挑战
  • 4.3 MySQL 存储函数
  • 【Python刷题】动态规划相关问题
  • 2024年9月中国电子学会青少年软件编程(Python)等级考试试卷(六级)答案 + 解析
  • 论文阅读:SIMBA: single-cell embedding along with features
  • d3-quadtree 的属性、方法、示例
  • 初次体验加猜测信息安全管理与评估国赛阶段训练习
  • 在WSUS中删除更新
  • 5分钟轻松搭建Immich图片管理软件并实现公网远程传输照片
  • 数据集-目标检测系列- 昙花(昙花一现) 检测数据集 epiphyllum >> DataBall
  • 开源POC库推荐
  • vue3项目部署在阿里云轻量应用服务器上
  • javascrip页面交互
  • 【U盘车载音乐】某宝198的3068首车载专用音乐合集【高音质】24G
  • 【论文阅读】WGSR
  • 打造智能化在线教育平台详解:教培网校APP的架构设计与实现
  • 使用同一个链接,如何实现PC打开是web应用,手机打开是一个H5应用
  • STM32-- 调试 -日志输出
  • Python爬虫案例八:抓取597招聘网信息并用xlutils进行excel数据的保存
  • 小试牛刀-Anchor安装和基础测试
  • 51单片机基础01 单片机最小系统
  • RocketMQ文件刷盘机制深度解析与Java模拟实现