点击上方 程序员成长指北,关注公众号
回复1,加入高级Node交流群
你知道<Suspense>
组件吗?你知道<Suspense>
如何管理 Vue app 的异步依赖吗?你知道<Suspense>
如何改进加载状态吗?
不知道?那就一起来学习一下吧。
<Suspense>
组件是 Vue 中的一个实验性功能,旨在帮助管理组件树中的异步依赖项。
虽然它目前处于实验阶段,但这是一种在处理异步组件,特别是处理加载状态的一个新的强大方法。
Suspense 解决了什么问题?
我们知道,但凡我们处理依赖于异步数据的组件时,通常需要手动管理加载状态。一听到手动二字,就能脑补一系列麻烦了。
举个例子,假设你有一个仪表板组件,组件包含多个嵌套组件,而这些嵌套组件每个又都依赖于异步获取的数据。
如果不使用<Suspense>
,那么因为这些组件中的每一个都需要自己的加载逻辑,所以很可能会导致陆续弹出不同的加载提示框,哎呀妈呀,这是多么糟糕的用户体验呀!
而使用<Suspense>
,管理加载状态变得易如反掌。因为组件不需要各自处理自己的加载状态,<Suspense>
允许你在等待解析组件树中的所有异步依赖项时,显示单个加载状态。
<Suspense>
如何工作?
<Suspense>
<!-- Component with async dependencies -->
<UserProfile />
<!-- Loading state via #fallback slot -->
<template #fallback>
<div class="spinner">Loading user profile...</div>
</template>
</Suspense>
<Suspense>
组件通过包装其他组件来工作。它有两个插槽:#default
和#fallback
。
#default
插槽包含一切准备就绪后就应该显示的组件和内容。#fallback
插槽是定义在等待异步操作完成时应显示的内容的位置。
在渲染组件时,Vue 会尝试渲染#default
插槽中的内容。一旦遇到异步依赖项(例如使用async setup()
的组件),就会切换到#fallback
插槽,直到一切准备就绪。
关于异步依赖项<Suspense>
可以等待两种类型的异步依赖项:
有 async setup()
钩子的组件:如果组件的setup
函数是异步的,就自动成为<Suspense>
的异步依赖项。
<script setup>
const data = await fetchData();
</script>
<template>
<div>{{ data }}</div>
</template>
异步组件:显式定义为异步的组件。如果这些异步组件是 <Suspense>
组件树的一部分,那么由<Suspense>
管理它们的加载状态。
<script>
export default {
async setup() {
const data = await fetchData();
return { data };
}
}
</script>
<template>
<div>{{ data }}</div>
</template>
处理<Suspense>
事件
<Suspense>
组件发出三个关键事件:pending
、resolve
和fallback
。
pending
:组件进入 pending 状态时触发,表示异步依赖正在解析中。
<Suspense @pending="handlePending">
<template #default>
<UserProfile />
</template>
<template #fallback>
<div class="spinner">Loading...</div>
</template>
</Suspense>
<script setup>
function handlePending() {
console.log('Loading state started');
}
</script>
resolve
:一旦#default
插槽中的内容完成加载并准备好显示就会发出。
<Suspense @resolve="handleResolve">
<template #default>
<UserProfile />
</template>
<template #fallback>
<div class="spinner">Loading...</div>
</template>
</Suspense>
<script setup>
function handleResolve() {
console.log('Content fully loaded');
}
</script>
fallback
:在显示#fallback
插槽内容时触发,通常是在等待异步操作完成时触发。
<Suspense @fallback="handleFallback">
<template #default>
<UserProfile />
</template>
<template #fallback>
<div class="spinner">Loading...</div>
</template>
</Suspense>
<script setup>
function handleFallback() {
console.log('Showing fallback content');
}
</script>
管理加载状态
<Suspense>
的美妙之处在于管理加载状态。当组件最初被渲染时,Vue 会尝试渲染默认内容。
这时如果遇到异步操作,就会显示回退内容。只有在解析完所有异步依赖项后,才会显示默认内容。
<Suspense>
<!-- Dashboard with async data -->
<UserDashboard />
<!-- Custom loading state -->
<template #fallback>
<div class="loading">Loading dashboard, please wait...</div>
</template>
</Suspense>
你有没有发现,管理复杂的加载场景变得容易了呢?是的,因为整个组件树中再也不用分散多个加载指示器。
处理错误
虽然 <Suspense>
非常适合管理加载状态,但它并不能直接处理错误。所以对于错误处理,我们得另想法子:Vue 的errorCaptured
选项,或者父组件中的onErrorCaptured()
钩子皆可。
与其他 Vue 组件组合应用
如果你想要<Suspense>
与诸如<Transition>
、<KeepAlive>
、<RouterView>
这些组件一起用,那么记得嵌套顺序很重要。
<RouterView v-slot="{ Component }">
<template v-if="Component">
<Transition mode="out-in">
<KeepAlive>
<Suspense>
<!-- Main settings content -->
<component :is="Component" />
<!-- Loading spinner -->
<template #fallback>
<div class="loading">Loading settings...</div>
</template>
</Suspense>
</KeepAlive>
</Transition>
</template>
</RouterView>
只有像上面这样有序地设置,我们才能顺利组合过渡、缓存和异步处理。
嵌套的<Suspense>
如果遇到更复杂的应用程序,那么我们还可能遇到嵌套的异步组件。别怕,我们有嵌套的<Suspense>
组件,可以独立控制深度嵌套组件的加载状态。
<Suspense>
<AsyncUserProfile>
<Suspense suspensible>
<AsyncUserDetails />
</Suspense>
</AsyncUserProfile>
</Suspense>
设置suspensible
prop 确保了内部的<Suspense>
的集成,从而允许我们对加载状态进行更精确的控制。赞。
最后的话
看到这儿,大家对<Suspense>
是不是有了更深刻的理解了呢?学习不是一朝一夕的事,不积硅步无以至千里。
学习快乐,编码快乐!
“原文链接:
https://www.trevorlasn.com/blog/understanding-vue-suspense
END
我组建了一个氛围特别好的 Node.js 社群,里面有很多 Node.js小伙伴,如果你对Node.js学习感兴趣的话(后续有计划也可以),我们可以一起进行Node.js相关的交流、学习、共建。下方加 考拉 好友回复「Node」即可。
“分享、点赞、在看” 支持一波👍