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
  • implementationdelay.timeout.error.loading
  • High order componentprops,event,slots.refThe passthrough
  • Can beretry

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