From 0d85bd88f07877d8bef1d9807232cca465c58aa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Fern=C3=A1ndez?= Date: Thu, 4 Apr 2024 18:19:03 +0000 Subject: [PATCH] feat(Suspense): add suspensible prop information Signed-off-by: GitHub --- src/api/built-in-components.md | 4 ++++ src/guide/built-ins/suspense.md | 34 +++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/api/built-in-components.md b/src/api/built-in-components.md index 0a37ad944e..07dfed6afb 100644 --- a/src/api/built-in-components.md +++ b/src/api/built-in-components.md @@ -318,6 +318,7 @@ Used for orchestrating nested async dependencies in a component tree. ```ts interface SuspenseProps { timeout?: string | number + suspensible?: boolean } ``` @@ -333,4 +334,7 @@ Used for orchestrating nested async dependencies in a component tree. If it encounters async dependencies ([Async Components](/guide/components/async) and components with [`async setup()`](/guide/built-ins/suspense#async-setup)) while rendering the default slot, it will wait until all of them are resolved before displaying the default slot. + By setting the Suspense as `suspensible`, all the async dependency handling + will be handled by the parent Suspense. See [implementation details](https://github.com/vuejs/core/pull/6736) + - **See also** [Guide - Suspense](/guide/built-ins/suspense) diff --git a/src/guide/built-ins/suspense.md b/src/guide/built-ins/suspense.md index f116ec94e5..3ab9002ee6 100644 --- a/src/guide/built-ins/suspense.md +++ b/src/guide/built-ins/suspense.md @@ -133,6 +133,40 @@ The following example shows how to nest these components so that they all behave Vue Router has built-in support for [lazily loading components](https://router.vuejs.org/guide/advanced/lazy-loading.html) using dynamic imports. These are distinct from async components and currently they will not trigger ``. However, they can still have async components as descendants and those can trigger `` in the usual way. +## Nested Suspense + +When we have multiple async components (common for nested or layout-based routes) like this: + +```vue-html + + + + + +``` + +`` creates a boundary that will resolve all the async components down the tree, +as expected. However, when we change `DynamicAsyncOuter`, `` awaits it correctly, but when we change `DynamicAsyncInner`, +the nested `DynamicAsyncInner` renders an empty node until it has been resolved (instead of the previous one or fallback slot). + +In order to solve that, we could have a nested suspense to handle the patch for the nested component, like: + +```vue-html + + + + + + + +``` + +If you don't set the `suspensible` prop, the inner `` will be treated like a sync component by the parent ``. +That means that it has its own fallback slot and if both `Dynamic` components change at the same time, +there might be empty nodes and multiple patching cycles while the child `` is loading its own dependency tree, +which might not be desirable. When it's set, all the async dependency handling is given to the parent `` (including the events emitted) +and the inner `` serves solely as another boundary for the dependency resolution and patching. + --- **Related**