Suspense Basic Use
IO /articles/vu…
Suspense document has not been released on the official website, because it is a feature and the API is not stable yet. There will also be a pop-up prompt when using.
is an experimental feature and its API will likely change.
Suspense is known to provide slots for fallbacks for asynchronous setup components.
DefineAsyncComponent is also known to provide lazy loading of asynchronous components. The functions are very similar. And it is mentioned in the documentation that defineAsyncComponent can be used with Suspense. However, some options will be invalid. The document
Using asynchronous components with Suspense is suspended by default. This means that if it has a girl in Suspense> in the parent chain, it will be treated as an asynchronous dependency of that girl. In this case, the load status is controlled by
, and the component’s own load, error, delay, and timeout options are ignored.
So if you want to use it, you want to abstract out a common method and simplify the call.
Realize the point
- Dynamic path import for import functions
- implementation
delay
.timeout
.error
.loading
- High order component
props
,event
,slots
.ref
The passthrough - Can be
retry
Part of the main implementation code
function asyncLoader (componentPath, options = {}) {
return {
name: 'asyncLoaderWrapper'.emits: ['resolve'.'fallback'.'pending'].setup(props, context) {
const { retry, error, setComponentLoadStatus } = useComponentStatus()
// ...
const instance = getCurrentInstance()
return (self) = > {
if (error.value) {
// Make errorComponent retry
return h(errorComponent, { error: error.value, retry })
}
let asynComponent = null
// Asynchronous setup component
if (typeof componentPath === 'object' && componentPath.setup) {
const originSetup = componentPath.setup
const { minTime } = defineAsyncOptions
// Loading display, minimum delay parameter, keep loading longer, prevent flashing
if (minTime) {
componentPath.setup = function () {
return Promise.all([originSetup.call(this), sleep(minTime)]).then(([setupState]) = > {
return setupState
})
}
}
asynComponent = componentPath
} else if (typeof componentPath === 'string') {
// Asynchronous lazy loading of components
asynComponent = optionAsyncLoader(componentPath, defineAsyncOptions)
} else {
return null
}
Attrs events slots passthrough
const defaultChildComponent = h(asynComponent, self.$attrs, instance.vnode.children)
defaultChildComponent.ref = instance.vnode.ref
return h(Suspense, null, {
default: defaultChildComponent,
fallback: h({
setup() {
/ / delay implementation
const { delayed } = useDelay(delay)
return () = >! delayed.value ? h(loadingComponent) :null}})})}}}}Copy the code
demo
The complete code
demo
code
Ability is limited. If there is something wrong, welcome to point out
TODO
Support for typescipt with additional type definitions