VUE中的组件加载方式

news/2025/2/22 11:11:54

加载方式有哪些,及如何进行选择

常规的静态引入是在组件初始化时就加载所有依赖的组件,而懒加载则是等到组件需要被渲染的时候才加载。

对于大型应用,可能会有很多组件,如果一开始都加载,可能会影响首屏加载时间。如果某些组件在首屏不需要,比如弹窗或者标签页里的内容,那么懒加载会更好,减少初始加载时间,实现时使用动态导入和异步组件,同时注意处理加载状态和错误处理。。反之,如果组件在页面初始化时就必须显示,那么静态加载更合适,因为懒加载可能会导致组件显示延迟,甚至出现闪烁。

首屏必需的组件静态加载,非必需的懒加载。根据组件的使用频率和重要性,结合同步和异步加载。

两种加载策略对比

1.静态加载(初始加载/同步加载)

优点:组件立即可用,无渲染延迟

缺点:如果组件较多或较大,会增加初始加载时间,影响首屏渲染速度。

适合场景:首屏核心组件、高概率使用的组件、小型组件

2.异步加载(按需加载)

优点:减小初始包体积,提升首屏速度

缺点:首次渲染需要加载时间,可能造成短暂延迟。实现稍微复杂,需要处理加载状态(如加载中、加载失败等)。

适合场景:非首屏组件、弹窗/抽屉等交互型组件、复杂大型组件

代码示例

1. 静态加载

<template>

  <div>

    <ComponentA />

    <ComponentB />

  </div>

</template>


<script setup>

// 导入组件

import ComponentA from './ComponentA.vue';

import ComponentB from './ComponentB.vue';

</script>

2. 异步加载

2.1Vue的defineAsyncComponent来按需加载组件。
<template>

  <div>

    <ComponentA />

    <ComponentB />

  </div>

</template>


<script setup>

import { defineAsyncComponent } from 'vue';

// 异步导入 LoadingSpinner 组件

import LoadingSpinner from './LoadingSpinner.vue';


// 定义异步组件 ComponentA

const ComponentA = defineAsyncComponent(() => import('./ComponentA.vue'));


// 定义异步组件 ComponentB

const ComponentB = defineAsyncComponent({

  loader: () => import('./ComponentB.vue'),

  loadingComponent: LoadingSpinner, // 加载状态组件

  delay: 200, // 延迟显示loading的时间

  timeout: 3000 // 超时时间

});

</script>
2.2使用动态导入
<template>

  <div>

    <ComponentA v-if="showComponentA" />

    <button @click="loadComponentA">Load Component A</button>

  </div>

</template>


<script setup>

import { ref } from 'vue';

const showComponentA = ref(false);

const ComponentA = shallowRef(null);//使用shallowRef来保存组件,因为组件对象不需要深度响应式,避免不必要的响应式开销

const loadComponentA = async()=> {

const module = await import('./ComponentA.vue');

ComponentA.value = module.default;

showComponentA.value = true;

}

</script>

若需调用引入组件中的某些方法,需进行一些处理。

问题原因

在 Vue 3 中,ref 绑定到组件实例时,ref 的值会在组件挂载完成后才被赋值。当你第一次调用 handleEdit 时,<Edit> 组件可能还没有完成挂载,因此 editRef.value 为 null。第二次调用时,组件已经挂载完成,所以 editRef.value 能够正确获取到组件实例。

根本原因

  1. 异步组件加载延迟:

    • 使用 defineAsyncComponent 加载的组件是异步的,组件加载和挂载需要时间。

    • 在 showEdit.value = true 后,组件开始加载,但加载和挂载是异步的,因此 editRef.value 不会立即被赋值。

  2. nextTick 的局限性:

    • nextTick 只会等待当前 DOM 更新完成,但不会等待异步组件加载完成。

    • 因此,即使使用 nextTick,editRef.value 仍然可能为 null。

1、使用 Promise 和 requestAnimationFrame 轮询检查

<Edit v-if="showEdit" ref="editRef" @fetch-data="fetchData" />

<script setup>

const editRef = ref(null)

  const showEdit = ref(false)

  const Edit = defineAsyncComponent(() => import('./components/edit'))

  const handleEdit = async (type, row) => {

    showEdit.value = true

    await new Promise((resolve) => {

      const checkComponentLoaded = () => {

        if (editRef.value && typeof editRef.value.showDialog === 'function') {

          resolve()

          requestAnimationFrame(checkComponentLoaded)

        }

      }

      checkComponentLoaded()

    })

    editRef.value.showDialog(type, row)

  }

</script>

* 使用 requestAnimationFrame 进行轮询会不断消耗性能,因为它会在每一帧都执行检查逻辑。

* 如果组件加载时间较长,轮询逻辑可能会持续运行,导致性能问题。

2、使用 watch 监听 editRef 的变化

<Edit v-if="showEdit" ref="editRef" @fetch-data="fetchData" />

const editRef = ref(null)

  const showEdit = ref(false)

  const Edit = defineAsyncComponent(() => import('./components/edit'))

  const handleEdit = async (type, row) => {

    showEdit.value = true

    const stopWatch = watch(

      editRef,

      (newVal) => {

        if (newVal && typeof newVal.showDialog === 'function') {

          newVal.showDialog(type, row)

          stopWatch() // 停止监听

        }

      },

      { immediate: true }

    )

  }

* 使用 watch 监听 editRef 的变化,避免了轮询的性能消耗。


http://www.niftyadmin.cn/n/5862169.html

相关文章

智能交通系统(Intelligent Transportation Systems):智慧城市中的交通革新

智能交通系统&#xff08;Intelligent Transportation Systems, ITS&#xff09;是利用先进的信息技术、通信技术、传感技术、计算机技术以及自动化技术等&#xff0c;来提升交通系统效率和安全性的一种交通管理方式。ITS通过收集和分析交通数据&#xff0c;智能化地调度、控制…

postgresql实时同步数据表mysql

应客户要求&#xff0c;需要同步数据到他们自己的数据库用于简单的数据分析&#xff0c;但这部分数据在postgresql&#xff0c;客户又不想再建pg&#xff0c;想直接同步到他们现有的mysql库&#xff0c;实时性倒是不要求。 考虑到 1、异构数据库同步 2、只同步指定客户的行数…

DeepSeek掘金——调用DeepSeek API接口 实现智能数据挖掘与分析

调用DeepSeek API接口:实现智能数据挖掘与分析 在当今数据驱动的时代,企业和开发者越来越依赖高效的数据挖掘与分析工具来获取有价值的洞察。DeepSeek作为一款先进的智能数据挖掘平台,提供了强大的API接口,帮助用户轻松集成其功能到自己的应用中。本文将详细介绍如何调用D…

最新本地部署 DeepSeekR1 蒸馏\满血量化版 + WebOpenUI 完整教程(Ubuntu\Linux系统\Ollama)

测试机为6133CPU(40Cores)256G D44*4090D 24G 一种方法是部署蒸馏版Distill模型。一种是部署Huggingface上unsloth的量化版模型 Ollama及模型安装 1.下载并安装ollama curl -fsSL https://ollama.com/install.sh | sh如果下载不动可以试试挂梯子或者再试几次 挂代理代码&…

tailwindcss学习03

01 入门 02 vue中接入 03 工具类优先 准备 vue.svg <svg viewBox"0 0 40 40" xmlns"http://www.w3.org/2000/svg"> <defs> <linearGradient x1"50%" y1"0%" x2"50%" y2"100%" id"a"&…

深度学习(2)-深度学习关键网络架构

关键网络架构 深度学习有4种类型的网络架构&#xff1a;密集连接网络、卷积神经网络、循环神经网络和Transformer。每种类型的模型都是针对特定的输入模式&#xff0c;网络架构包含了关于数据结构的假设&#xff0c;即模型搜索的假设空间。某种架构能否解决某个问题&#xff0…

书生大模型实战营12-InternVL 多模态模型部署微调

文章目录 L2——进阶岛InternVL 部署微调实践0.开发机创建与使用1.环境配置1.1.训练环境配置1.2.推理环境配置 2.LMDeploy部署2.1.LMDeploy基本用法介绍2.2.网页应用部署体验2.3 出错解决2.3.1 问题12.3.2 问题2 3.XTuner微调实践3.1.准备基本配置文件3.2.配置文件参数解读3.3.…

Spring MVC 对象转换器:初级开发者入门指南

Spring MVC 对象转换器&#xff1a;初级开发者入门指南 为什么需要对象转换器&#xff1f; 在 Web 应用中&#xff0c;我们经常需要处理不同类型的对象。例如&#xff1a;前端数据到后端对象 &#xff1a;用户通过表单提交的数据通常是HttpServletRequest 对象&#xff0c;我们…