To understand the asynchronous components in Vue3, read this article

Hello, I'm A bowl week , a front end that doesn't want to be drunk. If you are lucky enough to get your favor, I am very lucky~

Asynchronous component

Write in front

When our project reaches a certain scale, for some components, we don't want to load them all at the beginning, but when necessary; The purpose of this can improve the user experience.

In order to realize this function, Vue3 provides us with a method, defineAsyncComponent, which can pass two types of parameters, namely function type and object type. Next, we will study them respectively.

Pass factory functions as arguments

The basic usage of the defineAsyncComponent method is to receive a factory function. This factory function must return a Promise, and the resolve of Promise should return a component.

Let's take the project created by Vue Cli as an example. Here I made a slight modification to split the picture of the head into one component. The code is as follows:

<template>
  <logo-img />
  <hello-world msg="Welcome to Your Vue.js App" />
</template>

<script setup>
import LogoImg from './components/LogoImg.vue'
import HelloWorld from './components/HelloWorld.vue'
</script>

Now let's modify the < Hello world > component into an asynchronous component. The example code is as follows:

<template>
  <logo-img />
  <hello-world msg="Welcome to Your Vue.js App" />
</template>

<script setup>
import { defineAsyncComponent } from 'vue'
import LogoImg from './components/LogoImg.vue'

// Simple usage
const HelloWorld = defineAsyncComponent(() =>
  import('./components/HelloWorld.vue'),
)
</script>

In order to see the effect, we delay the execution of import. The example code is as follows:

<script setup>
import { defineAsyncComponent } from 'vue'
import LogoImg from './components/LogoImg.vue'

// Define a function that takes time to execute. t represents the delay time, and callback represents the function that needs to be executed. Optional
const time = (t, callback = () => {}) => {
  return new Promise(resolve => {
    setTimeout(() => {
      callback()
      resolve()
    }, t)
  })
}
// Define asynchronous components. This is written here to see the effect
const HelloWorld = defineAsyncComponent(() => {
  return new Promise((resolve, reject) => {
    ;(async function () {
      try {
        await time(2000)
        const res = await import('./components/HelloWorld.vue')
        resolve(res)
      } catch (error) {
        reject(error)
      }
    })()
  })
})
</script>

The running results of the code are as follows:

The < Hello world > component will not be loaded until 2s later.

Pass object type as parameter

The defineAsyncComponent method can also receive an object as a parameter, which has the following parameters:

  • loader: same as factory function;
  • loadingComponent: the component displayed when loading asynchronous components;
  • errorComponent: the component displayed when loading the component fails;
  • Delay: displays the delay time before loadingComponent, unit: ms, default: 200 ms;
  • Timeout: if timeout is provided and the time of loading components exceeds the set value, the wrong components will be displayed. The default value is Infinity (unit: milliseconds);
  • Suspend: asynchronous components can exit < suspend > control and always control their loading state. For details, please refer to file
  • onError: a function that contains four parameters: error, retry, fail, and attempts. These four parameters are the error object, the reloaded function, the function at the end of the loader, and the number of retries.

The following code shows the usage of the object type parameter of the defineAsyncComponent method:

<template>
  <logo-img />
  <hello-world msg="Welcome to Your Vue.js App" />
</template>

<script setup>
import { defineAsyncComponent } from 'vue'
import LogoImg from './components/LogoImg.vue'
import LoadingComponent from './components/loading.vue'
import ErrorComponent from './components/error.vue'

// Define a function that takes time to execute. t represents the delay time, and callback represents the function that needs to be executed. Optional
const time = (t, callback = () => {}) => {
  return new Promise(resolve => {
    setTimeout(() => {
      callback()
      resolve()
    }, t)
  })
}
// Record loading times
let count = 0
const HelloWorld = defineAsyncComponent({
  // Factory function
  loader: () => {
    return new Promise((resolve, reject) => {
      ;(async function () {
        await time(300)
        const res = await import('./components/HelloWorld.vue')
        if (++count < 3) {
          // Failed to load manual settings for the first two loads
          reject(res)
        } else {
          // More than 3 successes
          resolve(res)
        }
      })()
    })
  },
  loadingComponent: LoadingComponent,
  errorComponent: ErrorComponent,
  delay: 0,
  timeout: 1000,
  suspensible: false,
  onError(error, retry, fail, attempts) {
    // Note that retry/fail is like resolve/reject in promise:
    // One of them must be called to continue error handling.
    if (attempts < 3) {
      // Try again when the request has an error. You can try up to 3 times
      console.log(attempts)
      retry()
    } else {
      fail()
    }
  },
})
</script>

In the above code, we will request errors in the first two times when loading components, and only the third loading will succeed. The running results of the code are as follows:

If the load fails, the ErrorComponent component is displayed.

Write at the end

The above is the whole content of asynchronous components in Vue3. In fact, in general, it introduces the usage of defineasynccomponent API.

Keywords: Javascript Front-end Vue.js

Added by rgpayne on Fri, 11 Feb 2022 16:04:47 +0200