国外做电商网站,北京建设安全网络平台87,人力资源外包平台,蛋糕磨具网站开发背景Suspense (实验性功能) Suspense 是一项实验性功能。它不一定会最终成为稳定功能#xff0c;并且在稳定之前相关 API 也可能会发生变化。 Suspense 是一个内置组件#xff0c;用来在组件树中协调对异步依赖的处理。它让我们可以在组件树上层等待下层的多个嵌…Suspense (实验性功能) Suspense 是一项实验性功能。它不一定会最终成为稳定功能并且在稳定之前相关 API 也可能会发生变化。 Suspense 是一个内置组件用来在组件树中协调对异步依赖的处理。它让我们可以在组件树上层等待下层的多个嵌套异步依赖项解析完成并可以在等待时渲染一个加载状态。
异步依赖
要了解 Suspense 所解决的问题和它是如何与异步依赖进行交互的我们需要想象这样一种组件层级结构
Suspense
└─ Dashboard├─ Profile│ └─ FriendStatus组件有异步的 setup()└─ Content├─ ActivityFeed 异步组件└─ Stats异步组件在这个组件树中有多个嵌套组件要渲染出它们首先得解析一些异步资源。如果没有 Suspense则它们每个都需要处理自己的加载、报错和完成状态。在最坏的情况下我们可能会在页面上看到三个旋转的加载态在不同的时间显示出内容。
有了 Suspense 组件后我们就可以在等待整个多层级组件树中的各个异步依赖获取结果时在顶层展示出加载中或加载失败的状态。
Suspense 可以等待的异步依赖有两种 带有异步 setup() 钩子的组件。这也包含了使用 script setup 时有顶层 await 表达式的组件。 异步组件。
async setup()
如果使用 script setup那么顶层 await 表达式会自动让该组件成为一个异步依赖
export default {async setup() {const res await fetch(...)const posts await res.json()return {posts}}
}如果使用 script setup那么顶层 await 表达式会自动让该组件成为一个异步依赖
script setup
const res await fetch(...)
const posts await res.json()
/scripttemplate{{ posts }}
/template异步组件
步组件默认就是“suspensible”的。这意味着如果组件关系链上有一个 Suspense那么这个异步组件就会被当作这个 Suspense 的一个异步依赖。在这种情况下加载状态是由 Suspense 控制而该组件自己的加载、报错、延时和超时等选项都将被忽略。
异步组件也可以通过在选项中指定 suspensible: false 表明不用 Suspense 控制并让组件始终自己控制其加载状态。
加载中状态
Suspense 组件有两个插槽#default 和 #fallback。两个插槽都只允许一个直接子节点。在可能的时候都将显示默认槽中的节点。否则将显示后备槽中的节点。
Suspense!-- 具有深层异步依赖的组件 --Dashboard /!-- 在 #fallback 插槽中显示 “正在加载中” --template #fallbackLoading.../template
/Suspense在初始渲染时Suspens 将在内存中渲染其默认的插槽内容。如果在这个过程中遇到任何异步依赖则会进入挂起状态。在挂起状态期间展示的是后备内容。当所有遇到的异步依赖都完成后Suspens 会进入完成状态并将展示出默认插槽的内容。
如果在初次渲染时没有遇到异步依赖Suspense 会直接进入完成状态。
进入完成状态后只有当默认插槽的根节点被替换时 Suspense 才会回到挂起状态。组件树中新的更深层次的异步依赖不会造成 Suspense 回退到挂起状态。
发生回退时后备内容不会立即展示出来。相反Suspense 在等待新内容和异步依赖完成时会展示之前 #default 插槽的内容。这个行为可以通过一个 timeout prop 进行配置在等待渲染新内容耗时超过 timeout 之后Suspense 将会切换为展示后备内容。若 timeout 值为 0 将导致在替换默认内容时立即显示后备内容。
事件
Suspense 组件会触发三个事件pending、resolve 和 fallback。pending 事件是在进入挂起状态时触发。resolve 事件是在 default 插槽完成获取新内容时触发。fallback 事件则是在 fallback 插槽的内容显示时触发。
例如可以使用这些事件在加载新组件时在之前的 DOM 最上层显示一个加载指示器。
错误处理
Suspense 组件自身目前还不提供错误处理不过你可以使用 errorCaptured 选项或者 onErrorCaptured() 钩子在使用到 Suspense 的父组件中捕获和处理异步错误。
和其他组件结合
我们常常会将 Suspense 和 Transition、KeepAlive 等组件结合。要保证这些组件都能正常工作嵌套的顺序非常重要。 另外这些组件都通常与 Vue Router 中的 RouterView 组件结合使用。
下面的示例展示了如何嵌套这些组件使它们都能按照预期的方式运行。若想组合得更简单你也可以删除一些你不需要的组件
RouterView v-slot{ Component }template v-ifComponentTransition modeout-inKeepAliveSuspense!-- 主要内容 --component :isComponent/component!-- 加载中状态 --template #fallback正在加载.../template/Suspense/KeepAlive/Transition/template
/RouterView
Vue Router 使用动态导入对懒加载组件进行了内置支持。这些与异步组件不同目前他们不会触发 Suspense。但是它们仍然可以有异步组件作为后代这些组件可以照常触发 Suspense。
示例模拟加载两个异步组件最终同步渲染
子组件 1 promise 形式
组件 1 模拟文本内容 2 秒后变更值
script langts setup
import { ref } from vueconst result ref(0)const init () {return new Promise((resolve) {setTimeout(() {result.value 123return resolve({result})}, 3000)})
}
await init()
/scripttemplatediv classcontainerh1{{ result }}/h1/div
/templatestyle langscss scoped
.container {
}
/style
组件 2 模拟网络请求获取图片
script langts setup
import { ref } from vueimport axios from axiosconst rowData refany()
rowData.value await axios.get(https://dog.ceo/api/breeds/image/random)
/scripttemplatediv classcontainerdivimg classimg :srcrowData rowData?.data.message alt //div/div
/templatestyle langscss scoped
.container {img {width: 200px;height: 100px;}
}
/style
父组件异步加载两个组件
script langts setup
import { ref } from vue
import Com25_1 from /components/demo/Com25-1.vue
import Com25_2 from /components/demo/Com25-2.vue
/scripttemplatediv classcontainerh1suspense 示例/h1SuspensedivCom25_1/Com25_1Com25_2/Com25_2/div!-- 在 #fallback 插槽中显示 “Loading...” 或者显示一个骨架屏 --template #fallback显示 Loading... 或者显示一个骨架屏幕/template/Suspense/div
/templatestyle langscss scoped
.container {
}
/style
组件 1 需要两秒才会执行完成
组件 2 网络请求图片执行时间 (根据网络速度和服务器响应)
只有当都完成请求时 才会正常显示内容。
效果