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

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本&#xff1a; 3.8.1 语言&#xff1a; JavaScript/TypeScript、C、Java 环境&#xff1a;Window 参考&#xff1a;Java原生反射机制 您好&#xff0c;我是鹤九日&#xff01; 回顾 在上篇文章中&#xff1a;CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

大数据驱动企业决策智能化的路径与实践

&#x1f4dd;个人主页&#x1f339;&#xff1a;慌ZHANG-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 一、引言&#xff1a;数据驱动的企业竞争力重构 在这个瞬息万变的商业时代&#xff0c;“快者胜”的竞争逻辑愈发明显。企业如何在复杂环…...

MyBatis-Plus 常用条件构造方法

1.常用条件方法 方法 说明eq等于 ne不等于 <>gt大于 >ge大于等于 >lt小于 <le小于等于 <betweenBETWEEN 值1 AND 值2notBetweenNOT BETWEEN 值1 AND 值2likeLIKE %值%notLikeNOT LIKE %值%likeLeftLIKE %值likeRightLIKE 值%isNull字段 IS NULLisNotNull字段…...

代理服务器-LVS的3种模式与调度算法

作者介绍&#xff1a;简历上没有一个精通的运维工程师。请点击上方的蓝色《运维小路》关注我&#xff0c;下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 我们上一章介绍了Web服务器&#xff0c;其中以Nginx为主&#xff0c;本章我们来讲解几个代理软件&#xff1a…...

C++ 使用 ffmpeg 解码 rtsp 流并获取每帧的YUV数据

一、简介 FFmpeg 是一个‌开源的多媒体处理框架‌&#xff0c;非常适用于处理音视频的录制、转换、流化和播放。 二、代码 示例代码使用工作线程读取rtsp视频流&#xff0c;自动重连&#xff0c;支持手动退出&#xff0c;解码并将二进制文件保存下来。 注意&#xff1a; 代…...

Steam爬取相关游戏评测

## 因为是第一次爬取Steam。所以作为一次记录发出&#xff1b;有所错误欢迎指出。 无时间指定爬取 import requests import time import csv import osappid "553850" # 这里你也可以改成 #appid int(input()) max_reviews 10000 # 想爬多少条 # max_reviews…...

《架构即未来》笔记

思维导图 第一部分&#xff1a;可扩展性组织的人员配置 第二部分&#xff1a;构建可扩展的过程 第三部分&#xff1a;可扩展的架构方案 第四部分&#xff1a;其他的问题和挑战 资料 问软件工程研究所&#xff1a; https://www.sei.cmu.edu/ AKF公司博客: http://www.akfpart…...