Asynchronous components in vue3

What are asynchronous components

In Vue, when we register global or local components, they are "resolved and loaded immediately" synchronously. This means that when our program is initialized, all components will be downloaded into memory through the network and occupy certain resources in memory. Preloading all components will slow down the page's initial load time and performance, especially on mobile devices. To avoid this, Vue.js provides asynchronous components.

Why use asynchronous components

Asynchronous components can package our components separately and load them on demand, which can reduce initial page load time and reduce resource waste. When we need to work with routing, asynchronous components can also help us achieve on-demand loading and dynamic import. In this way, the route can be switched to implement the dynamic loader component when the component is called, which helps to improve the performance and response speed of the application.

Define asynchronous components

Vue3 uses defineAsyncComponent()to define asynchronous components. The input parameter of this API is a function that returns component options, and () => import()the function to import components.

The defineAsyncComponent method takes a load function that returns a Promise. The resolve callback method of this Promise should be called when the component definition is obtained from the server. We can also call reject(reason) to indicate that the load failed.

import {
    
     defineAsyncComponent } from 'vue'
const AsyncComponent = defineAsyncComponent(() => {
    
    
  return new Promise((resolve, reject) => {
    
    
    // ...从服务器获取组件
    resolve(/* 获取到的组件 */)
  })
}) 

ES module dynamic import also returns a Promise, so we will use it with defineAsyncComponent. Build tools like Vite and Webpack also support this syntax (and use them as code splitting points when packaging), so we can use it to import Vue single-file components as well:

import {
    
     defineAsyncComponent } from 'vue'
const AsyncComponent = defineAsyncComponent(() =>
  import('./components/MyComponent.vue')
)

The AsyncComponent obtained by the above code is an outer-wrapped component, and the function that loads the actual internal component will be called only when the page needs it to render.

Sample code:
Use the defineAsyncComponent function to define an asynchronous component, which returns a component object:

import {
    
     defineAsyncComponent } from 'vue'
const AsyncComponent = defineAsyncComponent(() => import('./MyComponent.vue'))
export default {
    
    
  components: {
    
    
    AsyncComponent
  }
}

An asynchronous component is defined above, and the component is registered through componentsthe object .

Asynchronous component loading and error states

When we perform asynchronous operations, it will inevitably involve slow network loading and loading errors. Vue also takes this situation into consideration when designing the defineAsyncComponent() component, which provides us with two configuration items: asynchronous loading The component used when the component is loaded loadingComponentand the component displayed after the load fails errorComponent. We need to create two custom components, LoadingComponent.vue and ErrorComponent.vue, to be used as the above two configuration items. The
sample code is as follows

const AsyncComp = defineAsyncComponent({
    
    
  // 加载函数
  loader: () => import('./MyComponent.vue'),
  // 加载异步组件时使用的组件
  loadingComponent: LoadingComponent,
  // 展示加载组件前的延迟时间,默认为 200ms
  delay: 200,

  // 加载失败后展示的组件
  errorComponent: ErrorComponent,
  // 如果提供了一个 timeout 时间限制,并超时了
  // 也会显示这里配置的报错组件,默认值是:Infinity
  timeout: 3000
})

The above code loads the LoadingComponent component first when the page is loaded, and there is a default 200ms delay before the loading component is displayed. If the loading fails, the ErrorComponent component will be called, and a timeout timeout can also be specified, and the error reporting component will also be rendered when the request takes longer than the specified time.

Use with Suspense

What is Suspense

Suspense is a built-in component that can uniformly manage the loading status of subcomponents, including the loading status of asynchronous components. It can have a loading state when loading components asynchronously, and display the components after the asynchronous components are created.

The Suspense component has two slots: #default and #fallback. Both slots allow only one direct child.

On initial render, Suspense will render its default #default slot contents in memory. If any asynchronous dependencies are encountered during this process, it will enter a pending state. During the suspended state, the #fallback fallback content is shown. When all encountered asynchronous dependencies are completed, Suspense will enter the completed state and will display the contents of the default slot #default.

If no asynchronous dependencies are encountered during the initial render, Suspense goes directly to the completion state.

After entering the completed state, Suspense will return to the suspended state only when the root node of the default slot #default is replaced. New deeper asynchronous dependencies in the component tree will not cause Suspense to fall back to a suspended state.

When a fallback occurs, the #fallback fallback content is not displayed immediately. Instead, Suspense will display the content of the previous #default slot while waiting for new content and asynchronous dependencies to complete. This behavior can be configured via a timeout prop: Suspense will switch to showing the #fallback fallback content after waiting for the timeout to render new content. A timeout value of 0 will cause the #fallback fallback content to be displayed immediately when replacing the #default default content.

Suspense event

The Suspense component fires three events: pending, resolve and fallback. The pending event is fired when the pending state is entered. The resolve event is fired when the default slot finishes fetching new content. The fallback event is triggered when the content of the fallback slot is displayed.

The sustainable feature of asynchronous components

Asynchronous components are "suspensible" by default. This means that if there is a Suspense on the component relationship chain, then this asynchronous component will be regarded as an asynchronous dependency of this Suspense. In this case, the loading state is controlled by Suspense, and the component's own loading, error reporting, delay and timeout options will be ignored.

Asynchronous components can also specify suspensible: false in the options to indicate that they do not need to be controlled by Suspense, and let the component always control its loading state by itself.

Sample code for using asynchronous components with Suspense

<template>
  <Suspense>
    <template #default>
      <AsyncComponent />
    </template>
    <template #fallback>
      <p>loading...</p>
    </template>
  </Suspense>
</template>

This is the end of the chat about asynchronous components in Vue3. Friends who like it like it, follow it and collect it.

Guess you like

Origin blog.csdn.net/w137160164/article/details/131132729