DefineAsyncComponent Asynchronous components

DefineAsyncComponent aims to create an asynchronous component that loads only when needed (similar to lazy loading)

parameter

For basic usage, defineAsyncComponent can accept a factory function that returns a Promise. The Promise’s resolve callback should be invoked after the server returns the component definition. You can also call reject(Reason) to indicate a load failure.

import { defineAsyncComponent } from 'vue'

const AsyncComp = defineAsyncComponent(() = >
  import('./components/AsyncComponent.vue')
)

app.component('async-component', AsyncComp)
Copy the code

When using local registrations, you can also provide a function that returns a Promise directly:

import { createApp, defineAsyncComponent } from 'vue'

createApp({
  // ...
  components: {
    AsyncComponent: defineAsyncComponent(() = >
      import('./components/AsyncComponent.vue'))}})Copy the code

For higher-order usage, defineAsyncComponent can accept an object:

The defineAsyncComponent method can also return objects of the following format:

import { defineAsyncComponent } from 'vue'

const AsyncComp = defineAsyncComponent({
  // Factory function
  loader: () = > import('./Foo.vue')
  // The component to use when loading asynchronous components
  loadingComponent: LoadingComponent,
  // The component to use when loading fails
  errorComponent: ErrorComponent,
  / / delay before displaying loadingComponent | default: 200 (ms)
  delay: 200.// If timeout is provided and the component takes longer to load than the set value, the error component will be displayed
  // Default: Infinity (that is, never timeout, in ms)
  timeout: 3000./ / defines whether the component can be hang | default value: true
  suspensible: false./ * * * *@param {*} Error Indicates the error information object *@param {*} Retry A function that indicates whether the promise loader should retry * when it loads a reject@param {*} Fail a function that tells the loader to quit@param {*} Maximum number of retries allowed */
  onError(error, retry, fail, attempts) {
    if (error.message.match(/fetch/) && attempts <= 3) {
      // Retry the request when an error occurs, up to three times
      retry()
    } else {
      // Note that retry/fail is like promise's resolve/reject:
      // One of these must be called to continue error handling.
      fail()
    }
  }
})
Copy the code

Any component that has an asynchronous setup method must be wrapped as setup returnsPromiseorasyncWrapped, whether or not we load asynchronously using defineAsyncComponent,

That is, sometimes we need to ask the interface on the back end to get the data before we can create a component. Creating an asynchronous setup function is a business requirement. Here we use setTimeout() to simulate API calls.

Let’s take a look at the test in our actual code:

Cross-step component test3.vue

<template> <div class="child"> I am async component </div> </template> <script> const getDataInfo = async () => {// async request await new Promise(resolve => setTimeout(resolve, 1000)); Const data = {name: 'Ma Long', address: 'Tokyo'}; return data; }; export default { async setup() { const data = await getDataInfo(); return { data }; }}; </script>Copy the code

The parent component demo. Vue

Suspense can not only show loaded components, but also use slot fallback to show fallback content (loading or degradation policies). The fallback contents are displayed during loading until the child component setup function parses and returns, and then renders the child component. Please note that V-if is at Suspense level.

<template> <div style="color: red"> <button @click="show = true">Load</button> <Suspense v-if="show"> <template #default> <child /> </template> <template #fallback> <p> </p> </template> </Suspense> </div> </template> <script> import Child from './test3.vue'; // Import {defineAsyncComponent} from 'vue'; // const LoginPopup = defineAsyncComponent(() => import('./test.vue')); export default { components: { Child }, data() { return { show: false }; }}; </script>Copy the code

The results are as follows:

1. Click the Load button to start loading the Child component;

2. “Loading” is displayed.

3. Wait until child’s setup returns asynchronously to display the child components.

For more details, please refer to Vue3’s official website: vue3js.cn/docs/zh/api…

Use ref to get Dom node content

In VUe2, the main function of ref is to facilitate the quick acquisition of DOM elements or components, because ref operation reduces the node consumption of DOM operation compared to Document.getelementByID.

In the last post, we talked about ref usage 1: make primitive types of data respond

Ref usage 2: get the DOM node

Examples of errors:

<template> <div class="container"> <img ref="imgRef" src="@/assets/images/dbTwo.png" /> </div> </template> <script> import { ref } from 'vue'; export default { setup() { const imgRef = ref(null); Console. log(' node ', imgref.value); return { imgRef }; }}; </script>Copy the code

Console print result:

Node null

In the life cycle of VUe3, setup is equivalent to beforeCreate and created of VUe2. At this time, Dom has not been created and rendered, so to obtain Dom nodes, the value must be in onMounted. Namely, the following three points are satisfied:

1. Declare in setup.

2. In onMounted.

**3. You must return **

<template> <div class="container"> <img ref="imgRef" src="@/assets/images/dbTwo.png" /> </div> </template> <script> import { onMounted, ref } from 'vue'; export default { setup() { // 1. Declare in setup const imgRef = ref(null); OnMounted (() => {console.log(' node ', imgref.value); // in onMounted, you can do xxoo things with the dom, such as echarts init, etc.}); Return {imgRef // 3. }}; </script>Copy the code