当前位置: 首页 > 科技观察

在Vue3中仍处于试验阶段什么是Suspense?

时间:2023-03-15 13:23:43 科技观察

悬念不是你想的那样。是的,它帮助我们处理异步组件,但它做的远不止于此。Suspense允许我们协调整个应用程序的加载状态,包括所有深度嵌套的组件。不像爆米花用户界面,加载无处不在,组件突然涌入到位。使用Suspense,我们可以拥有一个单一的、有组织的系统,可以同时加载所有内容。此外,Suspense为我们提供了细粒度的控制,因此如果需要,我们可以在两者之间实现一些东西。在本文中,我们将深入了解Suspense——它是什么、它能做什么以及如何使用它。首先,我们将仔细研究这些爆米花界面。那么,看看如何使用Suspense来解决这些问题。之后,尝试通过在整个应用程序中嵌套Suspense来获得更细粒度的控制。最后,快速浏览一下我们如何使用占位符来丰富我们的用户界面。PopcornUI--悬念示例地址:https://codesandbox.io/s/uncoordinated-loading-before-suspense-srh8ll?file=/src/App.vue。如果没有Suspense,每个组件都必须单独处理其加载状态。这可能会导致一些非常糟糕的用户体验,屏幕上会弹出多个加载按钮和内容,就像您正在制作爆米花一样。虽然,我们可以创建抽象组件来处理这些加载状态,但这比使用Suspense困难得多。有一个单一的点来管理加载状态比每个组件做自己的事情更容易维护。在示例中,我们使用BeforeSuspense组件来模拟一个内部处理加载状态的组件。将其命名为BeforeSuspense,因为一旦我们实现了Suspense,我们就会将其重构为WithSuspense组件。BeforeSuspense.vue最初将loading设置为true,因此会显示Spinner组件。然后,当setTimeout完成时,将loading设置为false,隐藏Spinner并使组件的背景变为绿色。在该组件中,还包含一个插槽,以便可以将其他组件放置在BeforeSuspense组件中:没什么特别的。只是传递给它们的一些具有不同时间值的嵌套组件。接下来,让我们看看如何使用Suspense组件改进爆米花用户界面。悬念示例地址:https://codesandbox.io/s/coordinated-loading-with-suspense-b6dcbi?file=/src/App.vue。现在,我们使用Suspense解决这个问题并将其转化为更好的用户体验。不过,首先,我们需要快速了解一下Suspense到底是什么?Suspense基础下面是Suspense部分的基本结构:对于UsingSuspense,将异步组件放入defaultslot,将fallbackloading状态放入fallbackslot。异步组件是以下两种情况之一:具有返回Promise的异步设置函数的组件,或脚本设置中的顶级等待。使用defineAsyncComponent异步加载的组件。无论哪种方式,我们最终都会得到一个开始未解决然后最终得到解决的Promise。当Promise没有resolved时,Suspense组件会显示fallbackslot的内容。然后,当Promise被解析时,它会在默认插槽中显示该异步组件。注意:这里没有错误处理路基。起初我以为有,但这是对悬念的普遍误解。如果想知道是什么导致了错误。可以使用onErrorCaptured钩子捕获错误,但这是一个独立于Suspense的特性。现在我们对Suspense有了一些了解,让我们回到我们的演示应用程序。管理异步依赖为了让Suspense管理我们的加载状态,我们首先需要将BeforeSuspense组件转换为异步组件。我们将其命名为WithSuspense,内容如下:我们已经完全删除了加载状态Spinner,因为该组件不再具有加载状态。因为这是一个异步组件,所以设置函数在完成加载之前不会返回。该组件只会在设置功能完成后加载。因此,与BeforeSuspense组件不同,WithSuspense组件内容在加载之前不会呈现。对于任何异步组件都是如此,无论它是如何使用的。在设置函数返回(如果同步)或解析(如果异步)之前,它不会呈现任何内容。有了WithSuspense组件,我们还需要重构我们的App组件,才能在Suspense组件中使用这个组件。结构和与之前相同,但这次位于Suspense组件的默认插槽中。我们还添加了一个回退槽来在加载时渲染我们的Spinner组件。在演示中,您会看到它显示加载按钮,直到加载所有组件。只有这样它才会显示现在完全加载的组件树。异步瀑布如果你仔细观察,你会发现组件并没有像你想象的那样并行加载。总加载时间不是基于最慢的组件(5秒)。相反,这个时间要长得多。这是因为Vue只会在父异步组件完全解析后才开始加载子组件。您可以通过将日志记录放入WithSuspense组件来对此进行测试。一个在安装开始时跟踪安装,一个在我们调用resolve之前。在使用BeforeSuspense组件的原始示例中,整个组件树无需等待即可挂载,并且所有“异步”操作都是并行启动的。这意味着Suspense有可能通过引入这种异步瀑布来影响性能。所以请记住这一点。嵌套Suspense隔离子树示例地址:https://codesandbox.io/s/nesting-suspense-wt0q7k?file=/src/App.vue。这是一个深度嵌套的组件,需要整整5秒才能加载,阻塞整个UI,尽管大多数组件加载完成的时间要快得多。但对我们来说,有一个解决方案。通过进一步嵌套第二个Suspense组件,我们可以在等待该组件完成加载的同时显示应用程序的其他部分。将其包装在第二个Suspense组件中,以将其与应用程序的其余部分隔离开来。Suspense组件本身是一个同步组件,所以它会在其父组件加载时加载。然后它将显示自己的后备内容,直到5秒结束。通过这样做,我们可以隔离应用程序中加载速度较慢的部分,从而减少首次交互的时间。在某些情况下,这可能是必要的,尤其是当您需要避免异步瀑布时。从功能的角度来看,这也是有意义的。您的应用程序的每个功能或“部分”都可以包装在它自己的Suspense组件中,因此每个功能都作为一个逻辑单元加载。当然,如果你用“Suspense”包裹每个组件,我们就回到了起点。我们可以选择以最合理的方式对加载状态进行批处理。使用占位符的悬念示例地址:https://codesandbox.io/s/placeholders-and-suspense-k5uzw0?占位符组件通常可以提供更好的体验,而不是使用单个微调器。这种方式向用户展示了将要显示的内容,并让他们在界面呈现之前有一种期待感。这是纺纱厂做不到的。这么说吧——它们很时髦,看起来很酷。因此,我们重构代码以使用占位符:我们排列了这些Placeholder组件并对其进行了样式化,使它们看起来与WithSuspense组件完全一样。这提供了加载和加载状态之间的无缝转换。在演示中,Placeholder组件为我们提供了背景上的CSS动画以创建脉动效果:.fast-gradient{background:linear-gradient(toright,rgba(255,255,255,0.1),rgba(255,255,255,0.4));背景大小:200%200%;动画:渐变2sease-in-outinfinite;}@keyframesgradient{0%{background-position:0%50%;}50%{背景位置:100%50%;}100%{背景位置:0%50%;}}总结爆米花的加载状态非常明显,很伤用户体验。幸运的是,Suspense是一个很棒的新功能,它为我们提供了很多选项来协调Vue应用程序中的加载状态。然而,在撰写本文时,Suspense仍处于实验阶段,因此请谨慎行事。有关其状态的最新信息,请参阅文档。