当前位置: 首页 > news >正文

vue3进阶用法之通过调用函数动态加载组件用法及示例

业务场景

假设现在有一个可能在全局任何地方调用的vue组件你会怎么办?非常简单,在app.vue下的router-view同级写上这个组件,在全局中加一个变量v-if判断这个变量就解决了!

tempalte中
<div><router-view /><YourComponent v-if="xxxStore.yourComponentVisible" />
</div>
js中
export const showComponent = () => {xxxStore.yourComponentVisible = true;
};
export const hideComponent = () => {xxxStore.yourComponentVisible = false;
};
某页面中
const handleSubmitForm = async() = >{showComponent()await reqGetUserInfo()hideComponent()
}

完美!!本文结束!!

一点也不好笑,我们进入正题。先看看需要了解到的方法,再来实现这个功能。

主要方法

  • h函数(更准确的名字应该叫createVnode)

从字面意思上来看,简单来说这个东西就是创建虚拟dom用的,在本文里面,它可以将你写的组件,转成vnode,也就是虚拟Dom。这里不做详细赘述。可以看下面文档链接。
api详细用法及信息

  • render函数

白话说就是把你的虚拟dom通过该方法挂载到某一个节点上面。这里不做详细赘述。可以看下面文档链接

api详细用法及信息

实现思路

看过了上面两个方法,先把组件转成虚拟dom,再将虚拟dom挂载到某节点上。那么知道了这些,实现这个功能就很简单了。这里用一个全局loading组件做示例。

简单版实现代码

import UploadLoading from '@/components/UploadLoading/index.vue'
import { render, h, ref, RendererNode, RendererElement, VNode, } from 'vue';
interface ILoadingRef {vnode: VNode<RendererNode, RendererElement, {[key: string]: any;}>;div: HTMLDivElement;
}
/*** 任何页面中调用该组件进行展示* @returns */
export const useUploadLoading = () => {const loadingRef = ref<ILoadingRef | null>(null);const showLoading = () => {// 避免重复挂载组件if (loadingRef.value) return// 在body上挂载一个divconst div = document.createElement('div');document.body.appendChild(div);// 把组件转成虚拟domconst vnode = h(UploadLoading);// 把这个组件挂载到上面创建的div里面render(vnode, div);loadingRef.value = { vnode, div };};const hideLoading = () => {if (!loadingRef.value) return// 在vue中卸载(unMounted)这个元素render(null, loadingRef.value.div);// Vue 卸载了这个元素,它仍然存在于 DOM 中,需要手动移除document.body.removeChild(loadingRef.value.div);loadingRef.value = null;};return { showLoading, hideLoading };
};

那么问题来了,为什么要走下面两个方法呢?这不是一个意思吗?

render(null, loadingRef.value.div);
document.body.removeChild(loadingRef.value.div);

其实这里看似一样其实另有玄机,render函数让这个组件执行所有的组件卸载生命周期,但元素还在dom上。比如说你的组件中的unMounted中有移除某些事件监听器的方法。要先走这一步让组件按正常流程卸载。

document.body.removeChild才是实际移除这个组件的操作

组件拓展

上面只是说简单实现。那么,现在这个loading组件中,有一个进度条,我需要实时更新这个进度条的进度,怎么办?

那就需要用到h函数的第二个参数了,我们把这个进度条的值传到组件里面。

组件中的props:

const props = defineProps({progress: {type: Number,default: 0}
});

核心两行代码:

   const vnode = h(UploadLoading, { progress: progress.value });loadingRef.value.vnode.component.props.progress = newProgress;

完整代码:

import UploadLoading from '@/components/UploadLoading/index.vue'
import { render, h, ref, RendererNode, RendererElement, VNode } from 'vue';
interface ILoadingRef {vnode: VNode<RendererNode, RendererElement, {[key: string]: any;}>;div: HTMLDivElement;
}
/*** 任何页面中调用该组件进行展示* @returns */
export const useUploadLoading = () => {const loadingRef = ref<ILoadingRef | null>(null);const progress = ref(0);const showLoading = () => {if (!loadingRef.value) {const div = document.createElement('div');document.body.appendChild(div);// 这里第二个参数传组件的props参数const vnode = h(UploadLoading, { progress: progress.value });render(vnode, div);loadingRef.value = { vnode, div };}};const hideLoading = () => {if (loadingRef.value) {render(null, loadingRef.value.div);document.body.removeChild(loadingRef.value.div);loadingRef.value = null;// 重置进度条progress.value = 0}};const updateProgress = (newProgress: number) => {progress.value = newProgress;if (loadingRef.value && loadingRef.value.vnode.component) {// 修改组件中的进度条值loadingRef.value.vnode.component.props.progress = newProgress;}};return { showLoading, hideLoading, updateProgress };
};

最后直接引入使用就行,我这里用oss文件分片上传做示例:

  /*** 分片上传文件*/async uploadFileByChunk(options: IChunkUploadOptions): Promise<string> {const { showLoading, hideLoading, updateProgress } = useUploadLoading();const yourOptions = {// 获取分片上传进度、断点和返回值。progress: (p: number) => {updateProgress(Math.floor(p * 100))}...省略其他代码}showLoading()try {await ossUpload(yourOptions)...省略其他代码} finally {hideLoading()}}

总结

vue官方文档那边虽然说了函数的使用方法,但没有列举这种业务场景。这里只是做一个简单的实例,其实可以通过这种方法实现其他更多的功能,比如说modal框等等等

相关文章:

vue3进阶用法之通过调用函数动态加载组件用法及示例

业务场景 假设现在有一个可能在全局任何地方调用的vue组件你会怎么办&#xff1f;非常简单&#xff0c;在app.vue下的router-view同级写上这个组件&#xff0c;在全局中加一个变量v-if判断这个变量就解决了&#xff01; tempalte中 <div><router-view /><You…...

线程和进程的关系

计算机是如何运行的&#xff1f;CPU 操作系统 进程管理 CPU 多核心 充分利用-> 并发编程&#xff0c;并发执行就算分时复用&#xff0c; 包括多进程编程。 多进程编程进程太重&#xff0c;创建进程&#xff0c;销毁进程开销比较大 &#xff0c;不利于频繁创建销毁进程&…...

《AI视频类工具之十二——​ EbSynth》

一.简介 官网:https://ebsynth.com/?ref=ai-bot.cn EbSynth是一款功能强大的视频风格转换工具,它利用先进的图像处理和计算机视觉技术,将静态艺术风格应用到视频中的每一帧,为视频创作者提供了全新的创作方式。 二.功能介绍 主要功能 视频转换:EbSynth 可以将视频转换…...

Facebook国内企业户、海外户、国内二不限户以及三不限户区别何在?

Facebook广告账户的类型和设置对于企业在不同市场中的广告活动至关重要。了解国内企业户、海外企业户&#xff0c;以及国内二不限户和三不限户的区别&#xff0c;可以帮助你更好地选择和管理广告账户。以下是对这些账户类型的详细解析。 一、Facebook海外企业广告账户 海外企业…...

修改 ASP.NET Core 应用程序运行后的默认端口

可以通过以下几种方法来实现。具体选择哪种方法取决于项目需求和环境设置。 方法 1&#xff1a;使用 appsettings.json 配置文件 你可以在 appsettings.json 中设置 Kestrel 的配置来更改默认端口。 打开 appsettings.json 文件&#xff0c;添加 Kestrel 配置&#xff1a; { …...

维基知识库系统Wiki.js本地Linux环境部署并配置公网地址远程访问

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

010集——按值传递、按引用传递等方法——C#学习笔记

按值传递参数 这是参数传递的默认方式。在这种方式下&#xff0c;当调用一个方法时&#xff0c;会为每个值参数创建一个新的存储位置。 实际参数的值会复制给形参&#xff0c;实参和形参使用的是两个不同内存中的值。所以&#xff0c;当形参的值发生改变时&#xff0c;不会影…...

Linux系统调优技巧

Linux系统调优技巧 Linux 性能调优技巧的深度分析及场景案例目录 1. Linux 性能调优的基础概念1.1 性能调优的目标1.2 常见的性能瓶颈 2. 系统监控与性能分析工具2.1 常用工具介绍2.2 实战案例&#xff1a;如何通过工具定位性能问题 3. CPU 性能调优3.1 CPU 负载分析3.2 CPU 调…...

计算机学习

不要只盯着计算机语言学习&#xff0c;你现在已经学习了C语言和Java&#xff0c;暑假又规划学习Python&#xff0c;最后你掌握的就是计算机语言包而已。 2. 建议你找一门想要深挖的语言&#xff0c;沿着这个方向继续往后学习知识就行。计算机语言是学不完的&#xff0c;而未来就…...

数字医学影像系统PACS源码,三甲以下医院都能满足,C#语言开发,C/S架构系统成熟稳定,支持二次开发项目使用。

数字医学影像系统&#xff08;RIS/PACS&#xff09;源码&#xff0c;三甲以下的医院都能满足。开发技术&#xff1a;C/S架构&#xff0c;C#开发语言&#xff0c;数据库服务器采用Oracle数据库。 PACS系统模块组成 &#xff1a; 工作站&#xff1a; 分诊工作站、超声工作站、放…...

C++语言基础|循环结构

C语言基础|循环结构 循环1. for语句2. while循环3. do…while语句 循环 在程序中&#xff0c;常常需要重复地执行某些操作。C提供了3种循环语句&#xff1a;for语句、while语句和do-while语句。在循环语句中&#xff0c;重复执行的操作叫做循环体。循环体可以是单条语句、块语…...

【学习笔记】解决在声音输出中找不到蓝牙耳机设备的问题

【学习笔记】在声音输出中找不到蓝牙耳机设备 在使用蓝牙耳机的时候&#xff0c;遇见一个问题&#xff0c;就是在电脑在连接蓝牙耳机之后&#xff0c;在声音输出中找不到蓝牙耳机设备&#xff0c;只能使用扬声器播放声音。电脑使用的是Windows 11系统。后来在网上寻找解决方案…...

PPPoE基础笔记

一、拨号原理 1.Discovery&#xff08;发现阶段&#xff09; PADI Client 发送广播的PADI报文&#xff0c;报文中包含Client想要的服务信息。 PADO Server收到PADI后&#xff0c;会向Client回复一个单播的PADO报文。 PADR Client 收到最先收到的PADO…...

开发组日志记录SPEC_v0.1.0

文章目录 开发组日志记录SPEC_v0.1.0目的设计逻辑1. User日志记录器1.1 记录器标签内容介绍1.2 程序打印User日志规则 2. Dev日志记录器2.1 记录器标签内容介绍2.2 程序打印Dev日志规则 3.代码说明3.1 代码详情3.2 使用说明 更新记录 时间版本内容修订者备注2024/08/150.1.0创…...

MySQL8 innoDB引擎的精髓

[client] port 3306 socket /var/lib/mysql/mysql.sock [mysql] #prompt"\umysqldb \R:\m:\s [\d]> " #关闭自动补全sql命令功能 no-auto-rehash ########################################################################### ##服务端参数配置 ######…...

【C语言实现花屏效果并打包程序为exe可执行文件】

说明&#xff1a;该程序为临摹改良(&#x1f600;)作品&#xff0c;源地址C/C屏幕恶搞程序 效果展示 上代码 #include <windows.h>#define NUM 11451LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);int main() // Renamed WinMain to main {static int iKeep[NU…...

数据结构——排序(2):选择排序+交换排序

目录 一、选择排序 &#xff08;1&#xff09;直接选择排序 ①思路 ②过程图示 ③代码实现 ④代码解释 ⑤优化 1.代码实现 2.过程图示 3.代码解释 4.注意 ⑥直接选择排序的复杂度 &#xff08;2&#xff09;堆排序 ①注意 ②代码实现 二、交换排序 &#xff08…...

jenkins升级踩坑记录

1. 直接用java 1.8版本启动最新版jenkins.war&#xff0c;直接失败 2. 下载java 11启动&#xff0c;依然失败&#xff0c;换成java17版本可以启动&#xff0c;但会报错 解决报错1&#xff1a; java.io.IOException: Failed to load: Parameterized Remote Trigger Plugin (Pa…...

mysql笔记第二篇

平时业务开发&#xff0c;大部分业务逻辑是使用sql还是代码编写呢&#xff1f; 这个每个公司可能要求不同&#xff0c;其实是每个公司负责人根据公司业务制定的规定。或者根本没有规定&#xff0c;每个负责单个项目的人领到需求直接开整&#xff0c;sql一把梭导致后面其他人维护…...

Facebook的区块链技术:提升数据安全与隐私保护

去中心化的优势 随着数字化时代的快速发展&#xff0c;数据安全和隐私保护已成为全球范围内备受关注的话题。Facebook作为全球最大的社交平台之一&#xff0c;正在积极探索如何通过区块链技术来提升数据的安全性和用户的隐私保护。区块链技术以其去中心化、不可篡改和透明的特…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器&#xff1a;Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展&#xff0c;AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术&#xff0c;在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

R 语言科研绘图第 55 期 --- 网络图-聚类

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…...

day36-多路IO复用

一、基本概念 &#xff08;服务器多客户端模型&#xff09; 定义&#xff1a;单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用&#xff1a;应用程序通常需要处理来自多条事件流中的事件&#xff0c;比如我现在用的电脑&#xff0c;需要同时处理键盘鼠标…...

android RelativeLayout布局

<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...

6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础

第三周 Day 3 &#x1f3af; 今日目标 理解类&#xff08;class&#xff09;和对象&#xff08;object&#xff09;的关系学会定义类的属性、方法和构造函数&#xff08;init&#xff09;掌握对象的创建与使用初识封装、继承和多态的基本概念&#xff08;预告&#xff09; &a…...

VisualXML全新升级 | 新增数据库编辑功能

VisualXML是一个功能强大的网络总线设计工具&#xff0c;专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑&#xff08;如DBC、LDF、ARXML、HEX等&#xff09;&#xff0c;并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...