Vue 3.0中异步组件defineAsyncComponent
在大型项目中,组件的体积可能会随着项目规模的增加而变得庞大。为了优化性能,我们可以将应用拆分为更小的块,并仅在需要时从服务器加载相关组件,这样的组件称为异步组件。
在 Vue 3 中,可以使用 defineAsyncComponent 方法来实现异步组件。
1. 异步组件
1.1. 组件的定义
import { defineAsyncComponent } from 'vue';const MyComponent = defineAsyncComponent(() => import('./components/MyComponent.vue'));
defineAsyncComponent 方法接收一个返回 Promise 的加载函数,ES 模块动态导入会返回一个 Promise,因此可以与 defineAsyncComponent 搭配使用。像 Vite 和 Webpack 这样的构建工具支持此语法,并将其作为代码分割点。
1.2. 使用异步组件
<script setup>
import { defineAsyncComponent } from 'vue';const AdminPage = defineAsyncComponent(() => import('./components/AdminPageComponent.vue'));
</script><template><AdminPage />
</template>
异步组件可以像普通组件一样使用和全局注册。通常异步组件我们会根据特定情况来使用,比如说以下场景:
1. 按照路由入口定义的异步组件;
2. 按照条件判断引入的异步组件;
因为只有组件在某一时机加载,这一特性才使得异步组件给应用加载带来性能提升,因为异步组件只在需要渲染时,才引入对应文件 chunk。
2. Suspense配合使用
<Suspense> 是一个内置组件,用来在组件树中协调对异步依赖的处理,它可以在等待异步组件加载时渲染一个加载状态。
<template><Suspense><template #default><MyComponent /></template><template #fallback><div>Loading...</div></template></Suspense>
</template><script setup>
import { defineAsyncComponent } from 'vue';const MyComponent = defineAsyncComponent(() => import('./components/MyComponent.vue'));
</script>
在上述代码中,当 MyComponent 组件正在加载时,<Suspense> 组件会显示 fallback 插槽中的内容。
3. 异步组件价值
为了分析异步组件对打包产物的影响,我们可以使用 rollup-plugin-visualizer 进行打包产物分析。
首先,安装该插件:然后在 vite.config.js 中配置插件:
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { visualizer } from 'rollup-plugin-visualizer';export default defineConfig({plugins: [vue(),visualizer({filename: './dist/report.html',open: true})]
});
构建项目后,打开生成的 report.html 文件,可以查看打包产物的可视化分析报告。示例分析如下:
3.1. 未使用异步组件
假设我们有一个普通组件 MyComponent.vue ,直接导入并使用:
<template><MyComponent />
</template><script setup>
import MyComponent from './components/MyComponent.vue';
</script>
在打包产物中,MyComponent 将被包含在主包内,导致主包体积较大。
3.2. 使用异步组件
使用 defineAsyncComponent 将 MyComponent 异步导入:
<template><Suspense><template #default><MyComponent /></template><template #fallback><div>Loading...</div></template></Suspense>
</template><script setup>import { defineAsyncComponent } from 'vue';
const MyComponent = defineAsyncComponent(() => import('./components/MyComponent.vue'));</script>
在打包产物中,MyComponent 将被拆分到一个独立的异步块中,仅在需要时加载,主包体积减小。
通过 rollup-plugin-visualizer 的可视化报告,可以清晰地看到未使用异步组件和使用异步组件后的打包体积差异。这种拆分可以显著提升应用的初始加载性能。
异步组件和 <Suspense> 组件的结合使用,可以优化大型应用的性能,减少主包体积,提升用户体验。通过打包分析工具如 rollup-plugin-visualizer,可以直观地查看异步组件带来的性能优化效果。在生产环境中,建议根据项目具体情况和稳定性需求,合理使用异步组件和 <Suspense> 组件。
4. 实现原理浅析
defineAsyncComponent 是一个高阶函数,它接收一个工厂函数作为参数,该工厂函数返回一个 Promise,用于异步加载组件。defineAsyncComponent 会返回一个新的组件,该组件内部处理了异步加载的逻辑。
4.1. 基本原理
1. 接收工厂函数: defineAsyncComponent 接收一个工厂函数,该工厂函数返回一个 Promise。
2. 返回异步组件: 返回的组件具有生命周期钩子和状态管理,用于处理加载过程、错误状态和超时等。
3. 加载组件: 在组件挂载时,执行工厂函数加载组件,并根据加载状态更新组件的显示。
4.2. 简单实例
以下是一个简化的 defineAsyncComponent 实现:
import { defineComponent, h, ref, onMounted, onUnmounted } from 'vue'export function defineAsyncComponent(loader) {return defineComponent({name: 'AsyncComponentWrapper',setup() {const component = ref(null)const error = ref(null)const loading = ref(true)onMounted(() => {loader().then((comp) => {component.value = comp.defaultloading.value = false}).catch((err) => {error.value = errloading.value = false})})return () => {if (loading.value) {return h('div', 'Loading...')} else if (error.value) {return h('div', `Error: ${error.value.message}`)} else if (component.value) {return h(component.value)}}}})
}
在这个简化版的实现中:
1. 定义状态:使用 ref 定义 component,error 和 loading 三个状态变量。
2. 组件挂载时加载:在 onMounted 钩子中调用传入的 loader 工厂函数来加载组件。
3. 处理加载结果:根据 Promise 的结果来更新状态变量。成功加载时,将组件赋值给 component,并设置 loading 为 false;加载失败时,将错误信息赋值给 error,并设置 loading 为 false。
4. 渲染逻辑:根据 loading,error 和 component 的状态来渲染不同的内容。
本示例代码展示了 defineAsyncComponent 的基本原理:通过工厂函数加载组件,并根据加载过程中的不同状态来更新显示内容。实际的 Vue 3 实现会更加复杂和健壮,支持更多的选项和功能,如加载超时、重试机制等
相关文章:
Vue 3.0中异步组件defineAsyncComponent
在大型项目中,组件的体积可能会随着项目规模的增加而变得庞大。为了优化性能,我们可以将应用拆分为更小的块,并仅在需要时从服务器加载相关组件,这样的组件称为异步组件。 在 Vue 3 中,可以使用 defineAsyncComponent…...
dedecms织梦全局变量调用方法总结
dedecms织梦的全局变量可以在/include/common.inc.php文件中看到,此文件内定义了大量的全局变量,详细自己去看看。 如果我们要实用dedeCMS织梦全局变量该如何调用: 第一种单独调用: {dede:global.变量名 /},注意闭合…...
新手到资深的Java开发编码规范
新手到资深的开发编码规范 一、前言二、命名规范:代码的 “第一印象”2.1 标识符命名原则2.2 命名的 “自描述性” 原则2.3 避免魔法值 三、代码格式规范:结构清晰的视觉美学3.1 缩进与空格3.2 代码块规范3.3 换行与断行 四、注释规范:代码的…...

asp.net core 添加 EntityFrame
1:Nuget 引入程序集 Microsoft.EntityFrameworkCore Microsoft.EntityFrameworkCore.SqlServer Microsoft.EntityFrameworkCore.SqlServer.Design Microsoft.EntityFrameworkCore.Tools 2:执行脚本 Scaffold-DbContext "Data Source.;Initial Ca…...

微软全新开源的Agentic Web网络项目:NLWeb,到底是什么 ?
目录 1、背景 2、NLWeb是什么? 3、NLWeb是如何工作的? 3.1 技术原理 3.2 对发布者的价值 3.3 核心团队与合作伙伴 4、快速入门指南 5、延伸阅读 Agentic:Agent的形容词,Agentic指系统由大型语言模型(LLM&#…...

Idea出现 100% classes 等
总是误点出来,每次又忘了怎么消除,在这里记录一下。 出现这样: 操作idea界面的:点击View->Tool Windows ->Coverage,然后关掉...

【学习笔记】计算机操作系统(五)—— 虚拟存储器
第五章 虚拟存储器 文章目录 第五章 虚拟存储器5.1 虚拟存储器概述5.1.1 常规存储管理方式的特征和局部性原理5.1.2 虚拟存储器的定义和特征5.1.3 虚拟存储器的实现方法 5.2 请求分页存储管理方式5.2.1 请求分页中的硬件支持5.2.2 请求分页中的内存分配5.2.3 页面调入策略 5.3 …...
构建基于全面业务数据的大数据与大模型企业护城河战略
引言:数据与AI驱动的专精企业未来 在数字化浪潮和人工智能技术飞速发展的今天,对于“专精特新”型企业而言,如何利用自身积累的深厚行业知识和独特的业务数据,结合大数据分析与大模型能力,构建难以被复制的竞争壁垒&a…...
centos系统redis-dump安装
1. Ruby 环境 Redis-dump 是一个 Ruby 工具,需先安装 Ruby 和 RubyGems。 安装依赖: sudo yum install -y curl gpg2 gcc-c patch readline readline-devel zlib zlib-devel libyaml-devel libffi-devel openssl-devel make bzip2 autoconf aut…...

乘最多水的容器 | 算法 | 给定一个整数数组。有n条垂线。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
在我们日常生活中,蓄水似乎是一个极为朴素的物理行为:两堵墙之间,注入水,看谁能装得更多。可如果换个角度,从算法的视角去看这个问题,它会变得怎样?你是否意识到,这样一个简单的问题…...
Python项目文件组织与PyCharm实践:打造高效开发环境
# Python项目文件组织与PyCharm实践:打造高效开发环境 在Python编程的世界里,合理组织项目文件是提升代码质量、增强可维护性以及促进团队协作的关键。同时,借助强大的集成开发环境(IDE)——PyCharm,我们能…...

【Java高阶面经:数据库篇】19、分库分表查询困境:无分库分表键时的高效应对
一、分库分表下的无分片键查询困境 在分布式数据库架构中,分库分表通过分片键(如买家ID)将数据分散存储,显著提升了单表性能和系统扩展性。然而,当业务需要从非分片键维度(如卖家ID)进行查询时,传统架构暴露出以下核心问题: 1.1 跨分片扫描的性能灾难 数据分散性:以…...

spring中的BeanFactoryAware接口详解
一、接口定义与核心作用 BeanFactoryAware 是 Spring 框架提供的一个回调接口,允许 Bean 在初始化阶段获取其所属的 BeanFactory 实例。该接口定义如下: public interface BeanFactoryAware {void setBeanFactory(BeanFactory beanFactory) throws Bea…...

Unity Hub打不开项目一直在加载
Unity Hub打不开项目,一直在加载。 运行环境:win10 解决方法:退还个人许可证,退出UnityHub重新登录后,再次获取个人许可证 Tips: 国内连续超过三天不登陆就需要激活一次。(每天登陆一次会自动续时间吗&…...

蓝桥杯19681 01背包
问题描述 有 N 件物品和一个体积为 M 的背包。第 i 个物品的体积为 vi,价值为 wi。每件物品只能使用一次。 请问可以通过什么样的方式选择物品,使得物品总体积不超过 M 的情况下总价值最大,输出这个最大价值即可。 输入格式 第一行输…...
服务器操作系统调优内核参数(方便查询)
fs.aio-max-nr1048576 #此参数限制并发未完成的异步请求数目,应该设置避免I/O子系统故障 fs.file-max1048575 #该参数决定了系统中所允许的文件句柄最大数目,文件句柄设置代表linux系统中可以打开的文件的数量 fs.inotify.max_user_watches8192000 #表…...

ElasticSearch导读
ElasticSearch 简介:ElasticSearch简称ES是一个开源的分布式搜素和数据分析引擎。是使用Java开发并且是当前最流行的开源的企业级搜索引擎,能够达到近实时搜索,它专门设计用于处理大规模的文本数据和实现高性能的全文搜索。它基于 Apache Luc…...

【机器学习】 关于外插修正随机梯度方法的数值实验
1. 随机梯度下降(SGD) 迭代格式: x k 1 x k − η k ∇ f i ( x k ) x_{k1} x_k - \eta_k \nabla f_i(x_k) xk1xk−ηk∇fi(xk) 其中, η k \eta_k ηk 为步长(可能递减), ∇ f…...

结构型:组合模式
目录 1、核心思想 2、实现方式 2.1 模式结构 2.2 实现案例 3、优缺点分析 4、适用场景 1、核心思想 目的:将总是在重复、迭代地显示的某种自相似性的结构(部分与整体结构特征相似),例如树形结构,以统一的方式处…...

windows 删除文件夹提示“操作无法完成,因为其中的文件夹或文件已在另一程序中打开”
windows 删除文件夹提示“操作无法完成,因为其中的文件夹或文件已在另一程序中打开” tomact已经关闭了,刚开始怀疑是tomcat关闭不彻底,但是任务管理器–》进程里根本没有java的进程了,由于是医院服务器、不方便重启 解决方法&am…...
使用 electron-builder 打包与发布 Electron 应用
基于 electron-vite-vue 项目结构 本文将基于 electron-vite-vue 脚手架,详细介绍如何使用 electron-builder 实现: ✅ 多平台打包(Windows / macOS / Linux)✅ 自动更新发布配置✅ 常用构建脚本与输出结构 📁 项目结…...

微信小程序中,解决lottie动画在真机不显示的问题
api部分 export function getRainInfo() {return onlineRequest({url: /ball/recruit/getRainInfo,method: get}); }data存储json数据 data:{rainJson:{} }onLoad方法获取json数据 onLoad(options) {let that thisgetRainInfo().then((res)>{that.setData({r…...

Wireshark 抓包工具使用
1.下载地址 https://2.na.dl.wireshark.org/win64/ 或者 Wireshark Go Deep 2.安装并打开 3.电脑设置热点,手机连接热点 4.手机发起网络请求,工具上选择WLAN。或者本地连接 5.点击查看抓包数据,过滤。最好用发送端ip过滤,s…...

大语言模型(LLM)本身是无状态的,怎么固化记忆
大语言模型(LLM)本身是无状态的,无法直接“记住”历史对话或用户特定信息 大语言模型(LLM)本身是无状态的,无法直接“记住”历史对话或用户特定信息,但可以通过架构改进、外部记忆整合、训练方法优化等方案实现上下文记忆能力。 一、模型内部记忆增强:让LLM“记住”…...

JUC入门(六)
12、四大函数式接口 Consumer<T>(消费者接口) 源码 功能 接收一个参数T,不返回任何结果。主要用于消费操作,例如打印日志、更新状态等。 使用场景 遍历集合并执行操作。 对象的字段赋值。 代码示例 import java.util.…...
std::chrono类的简单使用实例及分析
author: hjjdebug date: 2025年 05月 20日 星期二 14:36:17 CST descrip: std::chrono类的简单使用实例及分析 文章目录 1.实例代码:2. 代码分析:2.1 auto t1 std::chrono::high_resolution_clock::now();2.1.1 什么是 system_clock2.1.2 什么是 chrono::time_point?2.1.3 什…...
Git命令汇总(自用,持续更新update 5/23)
文章目录 Git常见命令1. 推送空提交2. 提交Clean-PR3. 回退add操作4. 交互式rebase4.1 切换模式4.2 保存与退出4.3 注意Rebase 5. 合并多个commit 问题一:Clone Github报错The TLS connection was non-properly terminated.TLS握手报错原因解决 问题二:F…...

window xampp apache使用腾讯云ssl证书配置https
下载腾讯云ssl证书: 编辑Apache根目录下 conf/httpd.conf 文件: #LoadModule ssl_module modules/mod_ssl.so和#Include conf/extra/httpd-ssl.conf,去掉前面的#号注释。 编辑Apache根目录下 conf/httpd-ssl.conf 文件: <Vi…...
MATLAB求解二元一次方程组基础教程
MATLAB求解二元一次方程组基础教程 一、二元一次方程组简介 二元一次方程组是包含两个未知数(x和y)的一组方程,每个方程中未知数的最高次数为1。一般形式为: a₁x b₁y c₁ a₂x b₂y c₂其中a₁, b₁, c₁, a₂, b₂, c₂为已知系数。 二、MATL…...
Android13 wifi设置国家码详解
Android13 wifi设置国家码详解 文章目录 Android13 wifi设置国家码详解一、前言二、设置wifi国家码相关代码1、adb或者串口也能设置和获取当前国家码(1)查询命令的方式(2)获取和设置国家码的示例 2、Java代码设置国家码3、获取当前…...