By Apoorv Tyagi
Translator: Front-end small wisdom
Source: dev
Have a dream, have dry goods, wechat search [big move world] pay attention to this in the wee hours of the morning is still brushing the dishes of the wisdom.
This paper making https://github.com/qq449245884/xiaozhi has included, has a complete line companies interview examination site, information, and my series of articles.
Using Vue3’s DefileAsyncComponent feature allows us to lazily load components, essentially creating an asynchronous component that will only be loaded when needed.
This is a good way to improve initial page loading, because our application will load into smaller chunks rather than having to load each component when the page loads.
In this article, we’ll learn all about defineAsyncComponent and look at an example of lazy loading of pop-ups.
DefineAsyncComponent is what?
const AsyncComp = defineAsyncComponent( () => new Promise((resolve, reject) => { resolve({ template: '<div>I am async! </div>' }) }) )
DefineAsyncComponent can accept a factory function that returns a Promise. The Promise’s resolve callback should be called after the server returns the component definition. You can also call Reject (Reason) to indicate a load failure.
DefineAsyncComponent can be imported from VUE and used:
import { defineAsyncComponent } from "vue"
// simple usage
const LoginPopup = defineAsyncComponent(() => import("./components/LoginPopup.vue"))
This is the easiest way to defineAsyncComponent. For higher order usage, defineAsyncComponent accepts an object:
Const AsyncPopup = defineAsyncComponent({loader: () => import("./ loginPopup.vue "), // LoadingComponent, / / loading fail to use the component errorComponent: errorComponent, / / delay before displaying LoadingComponent | default value: 200 delay (ms) : 1000, // If a timeout is provided and the loading time of the component exceeds the set value, an incorrect component will be displayed // Default value: Infinity (in ms) timeout: 3000})
Now that we’ve covered the basics, let’s do an example.
Load the Popup component asynchronously using defineAsyncComponent
In this example, we will use a login pop-up that is triggered by clicking a button.
We don’t need our application to load this component every time it is loaded, because it is only needed when the user performs a specific action.
Here is the login component implementation:
// LoginPopup.vue <template> <div class="popup"> <div class="content"> <h4> Login to your account </h4> <input type="text" placeholder="Email" /> <input type="password" placeholder="Password" /> <button> Log in </button> </div> </div> </template> <script> </script> <style scoped> .popup { position: fixed; width: 100%; top: ; left: ; height: 100%; Background-color: rgba(,,, 0.2); display: flex; justify-content: center; align-items: center; } .content { min-width: 200px; width: 30%; background: #fff; height: 200px; padding: 10px; border-radius: 5px; } input[type="text"], input[type="password"] { border: ; outline: ; border-bottom: 1px solid #eee; width: 80%; margin: auto; The font - size: 0.5 em. } button { border: ; margin-top: 50px; background-color:#8e44ad; color: #fff; padding: 5px 10px; The font - size: 0.5 em. } </style>
Import it into another component:
<template>
<button @click="show = true"> Login </button>
<login-popup v-if="show" />
</template>
<script>
import LoginPopup from './components/LoginPopup.vue'
export default {
components: { LoginPopup },
data() {
return {
show: false
}
}
}
</script>
We can use defineAsyncComponent and load it only when needed (use V-if to toggle when the button is clicked).
<! -- Use defineAsyncComponent --> <template> <button @click="show = true"> Login </button> <login-popup v-if="show" /> </template> <script> import { defineAsyncComponent } from 'vue' export default { components: { "LoginPopup" : defineAsyncComponent(() => import('./components/LoginPopup.vue')) }, data() { return { show: false } } } </script>
This usage looks similar to the above, no hurry, we F12 open the console.
If we don’t use defineAsyncComponent, once our page loads, we’ll see our application get loginpopup.vue from the server. While the performance issue is not as serious in this example, if we have dozens of components doing this, the performance is somewhat affected.
However, if we look at the same tag using defineAsyncComponent, we’ll notice that loginpopup.vue is missing when our page loads because it hasn’t been loaded yet.
However, if we switch the button, we can see it:
This helps us achieve optimal performance. We only want to load the required components when our page is initially loaded. Conditionally rendered components are often not needed when our pages load, so why make our applications load them?
How to use it with asynchronous Setup methods?
Any component with asynchronous setup methods must be wrapped in Suspense> whether or not we use defineAsyncComponent to load them asynchronously.
In short, creating an asynchronous Setup function is an option that allows our components to wait for some API call or other asynchronous operation before rendering.
Here is the component with asynchronous setup, using setTimeout() to simulate the API call
<template>
<div class="popup">
<div class="content">
<p> Loaded API: {{ article }} </p>
<h4> Login to your account </h4>
<input type="text" placeholder="Email" />
<input type="password" placeholder="Password" />
<button> Log in </button>
</div>
</div>
</template>
<script>
const getArticleInfo = async () => {
// wait 3 seconds to mimic API call
await new Promise(resolve => setTimeout(resolve, 1000));
const article = {
title: 'My Vue 3 Article',
author: 'Matt Maribojoc'
}
return article
}
export default {
async setup() {
const article = await getArticleInfo()
console.log(article)
return {
article
}
}
}
</script>
We can import it into a component with or without defineAsyncComponent:
import LoginPopup from './components/LoginPopup.vue'
// OR
const LoginPopup = defineAsyncComponent(() => import("./components/LoginPopup.vue"))
But if we want it to be rendered in our template, we need to package it in a Suspense element. This will wait for our setup to parse before attempting to render our component.
One of the nice features of Suspense is that you can show back content using slots and templates. The fallback content is displayed until the setup function parses and our component is ready to render. Note that v-if has been moved from the component itself to our Suspense component, so all fallbacks are shown.
<template>
<button @click="show = true"> Login </button>
<Suspense v-if="show">
<template #default>
<login-popup />
</template>
<template #fallback>
<p> Loading... </p>
</template>
</Suspense>
</template>
Here’s the result, and you’ll see “Loading…” , and then render the component after 3 seconds (the hard-coded value of setTimeout).
By default, all the components we defined using defineAsyncComponent are Suspense – able.
This means that if a component has Suspense in its parent chain, it will be treated as an asynchronous dependency for that component. Loadings, errors, delays, and timeouts for our components are ignored and handled by Suspense instead.
conclusion
DefineAsyncComponent is useful when building large projects that contain many components. When we use lazy load components, we load pages faster, improve the user experience, and ultimately increase app retention and conversion rates.
I’m curious to know what you think about this feature. If you already use it in your app, be sure to share it in the comments below.
~ over, I am small wisdom, today ready to do something ~
The possible bugs after the deployment of code can not be known in real time, in order to solve these bugs, spent a lot of time log debugging, here by the way to recommend you a good BUG monitoring toolFundebug.
Original: https://learnvue.co/2021/06/l…
communication
Have a dream, have dry goods, wechat search [big move world] pay attention to this in the wee hours of the morning is still brushing the dishes of the wisdom.
In this paper, making https://github.com/qq44924588… Has been included, there are a line of big factory interview complete test points, information and my series of articles.