使用 Vue 3 的 defineAsyncComponent 特性可以让我们延迟加载组件。这意味着它们仅在需要时从服务器加载。

这是改善初始页面加载的好方法,因为我们的应用程序将以较小的块加载,而不必在页面加载时加载每个组件。

在本教程中,我们将学习 defineAsyncComponent 的全部内容,并看一个例子,该例子将一个弹出窗口的加载推迟到我们的应用程序需要的时候。

好了,让我们开始吧。

什么是defineAsyncComponent

// SOURCE: https://v3.vuejs.org/guide/component-dynamic-async.html
const AsyncComp = defineAsyncComponent(() =>new Promise((resolve, reject) => {resolve({template: '<div>I am async!</div>'})})
)

defineAsyncComponent 接受一个返回Promise的工厂函数。当我们成功地从服务器获取组件时,这个Promise应该会被 resolve ,如果出现错误则会被 reject

要使用它,我们必须从Vue中导入它,然后才能在脚本的其余部分中使用它。

我们也可以使用工厂函数中的 import ,轻松地从其他文件中添加Vue组件。

import { defineAsyncComponent } from "vue" // 简单使用
const LoginPopup = defineAsyncComponent(() => import("./components/LoginPopup.vue"))

这是使用 defineAsyncComponent 的最简单方法,但我们也可以传入一个完整的选项对象,配置几个更高级的参数。

// with options
const AsyncPopup = defineAsyncComponent({ loader: () => import("./LoginPopup.vue"),loadingComponent: LoadingComponent, /* 在加载时显示 */errorComponent: ErrorComponent, /* 显示是否有错误 */delay: 1000, /* 在显示加载组件之前延迟毫秒 */timeout: 3000 /* 这个毫秒之后的超时 */
})

就我个人而言,我发现自己更经常使用第一种较短的语法,它对我的大多数使用情况都有效,但这完全取决于你。

就这么简单,让我们进入我们的例子。

使用defineAsyncComponent延迟加载弹出组件

在本例中,我们将使用一个由单击按钮触发的登录弹出窗口。

每当我们的应用程序加载时,我们不需要我们的应用程序加载此组件,因为只有在用户执行特定操作时才需要它。

所以这就是我们的登录组件的样子,它只是通过用 position: fixed 将屏幕的其余部分涂黑来创建一个弹出窗口,并且有一些输入和一个提交按钮。

<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>

而不是像我们通常那样导入它并将其纳入我们的 components 选项中。

<!-- "Standard" way of doing things -->
<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>

虽然这在我们使用我们的应用程序时可能看起来是一样的,但让我们检查元素 > 网络来理解这个小而重要的区别。

如果我们不使用 defineAsyncComponent,一旦我们的页面加载,我们就会看到我们的应用程序从服务器上获得LoginPopup.vue。虽然在这个例子中,这可能不是最大的性能问题,但它仍然会减慢加载速度,如果我们有几十个组件这样做,它真的会加起来。

但是,如果我们使用 defineAsyncComponent 查看同一个选项卡,我们会注意到当我们的页面加载时,LoginPopup.vue 不见了,这是因为它还没有加载。

但是一旦我们点击我们的按钮并告诉我们的应用程序显示我们的弹出窗口,这时它就会从服务器加载,我们可以在网络标签中看到它。

这有助于我们实现最佳性能。我们只想在我们的页面初始加载时加载需要的组件。有条件渲染的组件在我们的页面加载时往往是不需要的,所以为什么要让我们的应用程序加载它们呢?

如何使用异步设置功能

无论我们是否使用 defineAsyncComponent 延迟加载,任何具有异步设置功能的组件都必须用 <Suspense> 包装。

简而言之,创建一个异步设置函数是我们的一个选择,可以让我们的组件在渲染前等待一些API调用或其他异步动作。

这是我们具有异步设置的组件。它使用 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 callawait 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 函数在尝试渲染我们的组件之前解析。

<template><button @click="show = true"> Login </button><Suspense v-if="show"><template #default><login-popup  /></template><template #fallback><p> Loading... </p></template></Suspense>
</template>

这就是结果。用户会看到 “正在加载…”,然后在3秒后(我们的setTimeout的硬编码值),我们的组件将渲染。

默认情况下,我们使用 defineAsyncComponent 定义的所有组件都是可暂停的。

这意味着如果一个组件的父链中有 Suspense,它将被视为该 Suspense 的一个异步依赖。我们的组件的加载、错误、延迟和超时选项将被忽略,而是由 Suspense 来处理。

最后的想法

defineAsyncComponent 在创建有几十个组件的大型项目时是有好处的。当我们进入到懒惰加载组件时,我们可以有更快的页面加载时间,改善用户体验,并最终提高你的应用程序的保留率和转换率。

我想知道你对这个功能的看法。如果你已经在你的应用中使用它了,请在下面的评论中告诉我。

Vue.js 中使用defineAsyncComponent 延迟加载组件相关推荐

  1. 【Vue.js】Vue.js中常用的UI组件库和Vue Router

    1.Vue生态中常用的UI组件库 1. vant 介绍 轻量级.可靠的移动端 Vue 组件库 有赞前端团队出品 GitHub地址:https://github.com/youzan/vant 特性 拥 ...

  2. vue.js中<Transition> 组件

    在vue.js中发现 这个过渡动画的组件 简单的可以使用 如果需要复杂的动画效果可以自己引入动画库

  3. Vue.js中的8种组件间的通信方式;3个组件实例是前6种通信的实例,组件直接复制粘贴即可看到运行结果

    文章目录 一.$children / $parent 二.props / $emit 三.eventBus 四.ref 五.provide / reject 六.$attrs / $listeners ...

  4. js 操作vuex数据_Vue.js中使用Vuex实现组件数据共享案例

    当组件中没有关联关系时,需要实现数据的传递共享,可以使用Vuex 先不管图片 一.安装 在vue cli3中创建项目时勾选这个组件就可以了 或者手动安装 npm install store --sav ...

  5. php动态写入vue,Vue.js中使用动态组件的方法

    本文介绍了如何在Vue.js中引用组件中的HTML元素.您可以通过使用Vue路由器或创建动态组件来切换视图或组件模板. Vue路由器用于在DOM中的视图或组件模板之间导航.要使用Vue路由器,请在ro ...

  6. html5怎么改为vue_是否还在疑惑Vue.js中组件的data为什么是函数类型而不是对象类型...

    点击上方"前端印象",选择"设为星标"第一时间关注技术干货! 引言 要理解本篇文章,必须具备JavaScript中基本数据类型和引用数据类型的概念,大家可以花两 ...

  7. 浅析Vue.js 中的条件渲染指令

    1 应用于单个元素 Vue.js 中的条件渲染指令可以根据表达式的值,来决定在 DOM 中是渲染还是销毁元素或组件. html: <div id="app"> < ...

  8. ie浏览器查看vue中js_浅析 Vue.js 中那些空间换时间的操作

    Hello,各位小伙伴,接下来的一段时间里,我会把我的课程<Vue.js 3.0 核心源码解析>中问题的答案陆续在我的公众号发布,由于课程的问题大多数都是开放性的问题,所以我的答案也不一定 ...

  9. Vue.js中的v-model指令(双向绑定)

    Vue.js中v-model的作用 v-model的作用和使用场景 1.v-model的作用--双向绑定 2.v-model双向绑定的使用场景--表单 3.总结 v-model的作用和使用场景 你好! ...

最新文章

  1. ZJU-java进阶笔记 第四周(继承与多态)
  2. 10-Armv8-A memory model guide
  3. 北大OJ百练——4075:矩阵旋转(C语言)
  4. Python 实例属性和类属性
  5. 江湖召集:.NET开发者们看过来,这场长沙的开发者技术大会正是为你精心准备的大餐...
  6. 把人工智能、机器学习、深度学习串一串,串一个同心圆
  7. linux c语言画太极,利用C语言的Cairo图形库绘制太极图实例教程
  8. ZeroC IceBox介绍及demo构建
  9. Redis数据类型及其命令
  10. android .9图片如何引用,Android调用相机拍照并返回路径和调用系统图库选择图片...
  11. java面经_字节跳动 暑期实习 广告部 后台开发 java 一二面经
  12. amtlib.dll被McAfee删除之后?
  13. 牛顿三次插值 matlab,matlab 牛顿插值法 三次样条插值法[行业二类]
  14. IT基础架构变革,Hitachi Vantara如何解决超融合(HCI)的真正痛点?
  15. 连续时间傅立叶变换和拉普拉斯变换
  16. 单片机定时音乐播放器
  17. 中国著名画家司志明画伟人获全国画界称赞,单幅被拍出65万
  18. Chamfer Distance--倒角距离
  19. RHEL5/6 加载 DVD yum源
  20. 成都计算机考研学校排名,成都十大考研学校排名

热门文章

  1. Linux内核MTD子系统七之Flash 存储器接口标准:CFI和JEDEC
  2. html网页设计模板网站
  3. 最新零基础C++逆向辅助+过驱动保护+lua
  4. 删除资源管理器中,设备和驱动器中存在的WPS网盘,百度网盘等图标
  5. 华为面试C语言真题(二)
  6. 你需要启用steam社区界面功能以进行购买_焦虑的Steam新版游戏库,与玩家们真正的担忧...
  7. [Delphi] Windows 外壳扩展编程入门实例
  8. IOS 学习笔记 iphone屏幕分辨率统计(全面)
  9. iphone、ipad屏幕分辨率
  10. google开源服务器apprtc的搭建