当前位置: 首页 > 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;正在积极探索如何通过区块链技术来提升数据的安全性和用户的隐私保护。区块链技术以其去中心化、不可篡改和透明的特…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...

CSS设置元素的宽度根据其内容自动调整

width: fit-content 是 CSS 中的一个属性值&#xff0c;用于设置元素的宽度根据其内容自动调整&#xff0c;确保宽度刚好容纳内容而不会超出。 效果对比 默认情况&#xff08;width: auto&#xff09;&#xff1a; 块级元素&#xff08;如 <div>&#xff09;会占满父容器…...