作者:Apoorv Tyagi
译者:前端小智
起源:dev
有幻想,有干货,微信搜寻 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。
本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试残缺考点、材料以及我的系列文章。
应用 Vue3 的 DefileAsyncComponent
性能可让咱们懒加载组件,说白了就是创立一个只有在须要时才会加载的异步组件。
这是改良初始页面加载的好办法,因为咱们的应用程序将加载到较小的块中而不是必须在页面加载时加载每个组件。
在本文中,咱们将学习无关 defineAsyncComponent
的所有常识,并学习一个懒加载弹出窗口的例子。
defineAsyncComponent 是啥?
const AsyncComp = defineAsyncComponent(() =>
new Promise((resolve, reject) => {
resolve({template: '<div>I am async!</div>'})
})
)
defineAsyncComponent
能够承受一个返回 Promise
的工厂函数。Promise 的 resolve
回调应该在服务端返回组件定义后被调用。你也能够调用 reject(reason)
来示意加载失败。
defineAsyncComponent
能够从 vue 中导入,并应用:
import {defineAsyncComponent} from "vue"
// simple usage
const LoginPopup = defineAsyncComponent(() => import("./components/LoginPopup.vue"))
这是 defineAsyncComponent
的最简略办法,对于高阶用法,defineAsyncComponent
能够承受一个对象:
const AsyncPopup = defineAsyncComponent({loader: () => import("./LoginPopup.vue"),
// 加载异步组件时要应用的组件
loadingComponent: LoadingComponent,
// 加载失败时要应用的组件
errorComponent: ErrorComponent,
// 在显示 loadingComponent 之前的提早 | 默认值:200(单位 ms)delay: 1000,
// 如果提供了 timeout,并且加载组件的工夫超过了设定值,将显示谬误组件
// 默认值:Infinity(即永不超时,单位 ms)timeout: 3000
})
根底曾经介绍完了,接着,咱们来做个例子。
应用 defineAsyncComponent 异步加载 Popup 组件
在这个例子中,咱们将应用一个由点击按钮触发的登录弹框。
咱们不须要咱们的应用程序在每次加载时都加载这个组件,因为只有在用户执行特定的动作时才须要它。
上面是 login 组件的实现:
// 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;
font-size: 0.5em;
}
button {
border: ;
margin-top: 50px;
background-color:#8e44ad;
color: #fff;
padding: 5px 10px;
font-size: 0.5em;
}
</style>
在其它组件中导入它:
<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>
咱们能够应用 defineAsyncComponent
,只在须要的时候加载它(按钮被点击时应用 v-if
来切换)。
<!-- 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>
这个用法看起来和下面的差不多,不急,咱们 F12
关上控制台。
如果咱们不应用defineAsyncComponent
,一旦咱们的页面加载,咱们就会看到咱们的应用程序从服务器上取得LoginPopup.vue
。尽管在这个例子中,性能问题不那么重大,但如果咱们有几十个组件这样做,性能上多多少少还是有影响的。
然而,如果咱们应用 defineAsyncComponent
查看同一个标签,会留神到,当咱们的页面加载时,LoginPopup.vue
是没有的,这是因为它还没有被加载。
但,如果切换按钮,咱们就能够看到它了:
这有助于咱们实现最佳性能。咱们只想在咱们的页面初始加载时加载须要的组件。有条件渲染的组件在咱们的页面加载时往往是不须要的,所以为什么要让咱们的应用程序加载它们呢?
如何与异步的 setup 办法一起应用?
不论咱们是否用 defineAsyncComponent
来异步加载,任何具备异步 setup
办法的组件都必须用 <Suspense>
来包装。
简而言之,创立一个异步 setup
函数是咱们的一种抉择,能够让咱们的组件在渲染前期待一些 API 调用或其余异步操作。
上面是带有异步 setup
的组件,应用 setTimeout()
模仿 API 调用
<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>
咱们能够应用或不应用 defineAsyncComponent
将它导入到组件中:
import LoginPopup from './components/LoginPopup.vue'
// OR
const LoginPopup = defineAsyncComponent(() => import("./components/LoginPopup.vue"))
但如果咱们想让它在咱们的模板中渲染,咱们须要把它包在一个 Suspense
元素中。这将期待咱们的setup
解析后,而后再尝试渲染咱们的组件。
Suspense
的一个很好的特点是,咱们能够应用槽和模板显示回退内容。回退内容将显示,直到 setup
函数解析,咱们的组件筹备好渲染。请留神,v-if
曾经从组件自身移到了咱们的 Suspense 组件上,所以所有回退内容都会显示。
<template>
<button @click="show = true"> Login </button>
<Suspense v-if="show">
<template #default>
<login-popup />
</template>
<template #fallback>
<p> Loading... </p>
</template>
</Suspense>
</template>
上面是运行后果,会看到 "Loading…"
,而后在 3
秒后 (setTimeout
的硬编码值)组件渲染。
默认状况下,咱们应用 defineAsyncComponent
定义的所有组件都是可 Suspense
的。
这意味着如果一个组件的父链中有 Suspense,它将被视为该 Suspense 的一个异步依赖。咱们的组件的加载、谬误、提早和超时选项将被疏忽,而是由 Suspense 来解决。
总结
当构建包许多组件的大型项目时,defineAsyncComponent
是十分有用的。当咱们应用懒加载组件时,能够更快地加载页面,改善用户体验,最终进步利用的留存率和转换率。
我很想晓得大家对这个个性的认识。如果你曾经在你的利用中应用它了,记得上面留言分享一下哦。
~ 完,我是小智,明天筹备去干点啥~
代码部署后可能存在的 BUG 没法实时晓得,预先为了解决这些 BUG,花了大量的工夫进行 log 调试,这边顺便给大家举荐一个好用的 BUG 监控工具 Fundebug。
原文:https://learnvue.co/2021/06/l…
交换
有幻想,有干货,微信搜寻 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。
本文 GitHub https://github.com/qq44924588… 已收录,有一线大厂面试残缺考点、材料以及我的系列文章。