vue3编程 -动态多开模态框实现方案

 页面按需弹出多个模态框:

 一、v-for方案:

                采用v-for提前生成多个模态框实例,采用这种方案的案例社区已经很多

二、采用h函数方案:

   代码如下,代码可运行:

   基本思路:

1. 封装模态框组件DialogModal

2.通过h()函数创建DialogModal的虚拟dom

3. 通过创建容器元素+vue的mount()函数进行挂载

4. 模态框关闭后需要解除挂载,通过vue的unmoun()函数

如果模态框是自行开发的,到此应该就可以结束了。但是,基于element plus的模态框,会存在当前模态框阻挡后面模态框点击的问题,解决方案如下:

.modal-class {pointer-events: none;
}
.el-overlay-dialog {pointer-events: none;
}
.el-dialog {pointer-events: auto;
}

完整代码如下: 

<script setup lang="ts">
import DialogModal from '@/components/DialogModal.vue'
import { ref, onUnmounted, h, createApp } from 'vue'
import { ElMessage } from 'element-plus'const modals = ref([])const showModal = () => {let num = Math.random()createModal({ title: 'test' + num, showMsg: 'hello' + num })
}const createModal = config => {const modalRef = ref()const modalInstance = h(DialogModal, {ref: modalRef,title: config.title,content: config.showMsg,onClosed: () => {removeModal(modalRef.value)},onConfirmed: () => {removeModal(modalRef.value)ElMessage.success('模态框已关闭')}})console.log('modalInstance', modalInstance)modals.value.push(modalRef)// 创建虚拟 DOM 并挂载到文档const container = document.createElement('div')container.id = 'modal-container' + Math.random()document.body.appendChild(container)const app = createApp(modalInstance)app.mount(container)return {unmount: () => {app.unmount()document.body.removeChild(container)}}
}const removeModal = modal => {if (modal) {modal.unmount()const index = modals.value.findIndex(m => m.component === modal)if (index !== -1) {modals.value.splice(index, 1)}}
}onUnmounted(() => {modals.value.forEach(modal => {modal.component.unmount()})
})
</script><template><div><el-button @click="showModal">显示模态框</el-button></div><router-view></router-view>
</template>
<template><div :class="{ scrollDialog: scrollVisible }"><el-dialogv-model="dialogVisible":width="props.width":destroy-on-close="true":close-on-click-modal="false":modal="false"draggable:z-index="-1":fullscreen="false"@close="closeDialog":modal-class="'modal-class'"><template v-slot:header><span class="cus-title">{{ props.title }}</span></template><slot>{{ props.showMsg }}</slot><template v-slot:footer><span v-if="props.dialogFoot || props.dialogFix" class="dialog-footer"><el-button v-if="props.dialogFoot" @click="closeDialog">{{ cancleName }}</el-button><el-button v-if="props.dialogFix" type="primary" @click="determine">{{ determineName }}</el-button></span></template></el-dialog></div>
</template>
<script setup lang="ts">
import { defineProps, ref, defineExpose, defineEmits } from 'vue'const emits = defineEmits(['determine', 'closeDialog'])const props = defineProps({width: {// 弹框宽度type: String,default: '480px'},title: {// 弹框模块名称type: String,default: () => {return ''}},showMsg: {// 展示的信息type: String,default: ''},dialogFoot: {// 显示取消代码type: Boolean,default: true},dialogFix: {// 显示确定按钮type: Boolean,default: true},determineName: {// 确定键名称type: String,default: '确认'},cancleName: {// 取消键名称type: String,default: '取消'}
})
// 弹框显示状态
let dialogVisible = ref(true)
// 控制滚动条样式,超过10条显示滚动条
let scrollVisible = ref(false)
/*** 打开模态框*/
function openDialog() {if (dialogVisible.value) {return}dialogVisible.value = true
}/*** 关闭模态框*/
function closeDialog() {if (!dialogVisible.value) {return}dialogVisible.value = falseemits('closeDialog') // 用户自定义取消后函数,例如:清空表单数据
}/*** @description: 确定事件* @param null* @return: null*/
function determine() {emits('determine') // 触发组件上的determine事件,用户自定义提交dialogVisible.value = false
}
/*** 对外提供打开和关闭模态框,控制模态框和滚动条的显隐*/
defineExpose({ closeDialog, openDialog, dialogVisible, scrollVisible })
</script>
<style scoped lang="scss">
// @import '@/assets/scss/auditPublic.scss';
.el-dialog__body {padding: 20px;
}
.el-dialog__footer {border-top: 1px solid #e9ebef;
}
.cus-title {width: 100%;text-overflow: ellipsis;white-space: nowrap;overflow: hidden;font-size: 16px;color: #031129;display: inline-block;
}
:deep(.el-transfer .el-transfer-panel__item.el-checkbox) {height: auto !important;
}:deep(.el-dialog__body) {max-height: 400px !important;
}.scrollDialog {:deep(.el-dialog__body) {overflow-y: auto !important;height: 400px !important;}
}
</style>
<style>
.modal-class {pointer-events: none;
}
.el-overlay-dialog {pointer-events: none;
}
.el-dialog {pointer-events: auto;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/51248.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker快速上手

Docker 前言一、基本组成二、常用命令2.1 Docker服务2.2 image相关命令2.3 Container相关命令 三、Docker Volume 容器卷3.1 匿名挂载3.2 具名挂载 四、Docker 网络模式4.1 bridge桥接模式4.2 host主机模式4.3 None模式4.4 Container模式4.5 Customer模式 前言 本篇文章不再赘…

读软件开发安全之道:概念、设计与实施08密码学(下)

1. 对称加密 1.1. symmetric encryption 1.2. 使用各方共享的密钥来隐藏数据 1.2.1. 对称加密在本质上依赖共享密钥 1.3. 所有加密都是通过对明文进行转换&#xff0c;把明文消息&#xff08;或者原始消息&#xff09;变成无法识别的形式&#xff08;也称为密文&#xff09…

LeetCode 热题100-69 有效的括号

有效的括号 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。每个右括号都有一个对应的相…

我的CSDN-----第128天创作纪念日

机缘 起初的我&#xff0c;是为了在学习代码的过程中通过写博客的方式来巩固自己的知识。后来在遇到不会的问题时可以在csdn上面查找&#xff0c;寻求一点思路&#xff0c;将学到的知识通过博客的方式呈现出来。 收获 每当发布一篇博客后&#xff0c;就会收到很多人的评论加关…

Adobe Animate (AN)软件安装,硬件配置(附安装包)

目录 一、Adobe An 软件简介 Adobe An 软件的特点 Adobe An 软件的优势 下载 二、Adobe An 软件安装 安装前的准备工作 安装过程中的注意事项 安装后的设置 三、Adobe An 软件使用 高级动画技巧 交互设计 优化与性能提升 四、Adobe An 软件快捷键 选择工具快捷键…

Linux 下命令行参数和环境变量

Linux 下命令行参数和环境变量 命令行参数为什么要有命令行参数谁可以做到结论 环境变量一些现象查看环境变量添加环境变量添加内存级环境变量永久有效 其他环境变量HOMEPWDSHELLHISTSIZE 自定义环境变量定义取消 本地变量整体理解环境变量环境变量的组织方式Linux 代码获取环境…

31. 高度过渡 带粘性分区标题的列表

高度过渡 当元素的高度未知时,将元素的高度从 0 过渡到 auto。 使用 transition 指定 max-height 的变化应该被过渡。使用 overflow: hidden 防止隐藏元素的内容溢出其容器。使用 max-height 指定 0 的初始高度。使用 :hover 伪类将 max-height 更改为由 JavaScript 设置的 --…

【机器人学】7-2.六自由度机器人自干涉检测-计算圆柱体的上下圆心坐标【附MATLAB代码】

目录 前言 机械臂几何参数 机器等效圆柱体坐标确定 MATLAB代码 前言 上一章介绍了机器人自干涉检测的总体算法&#xff0c;提出了算法的三个核心&#xff1a; 一 根据机械臂的几何数据以及DH参数&#xff0c;确定机械臂等效的圆柱体的上下圆心坐标。 二 将一个圆柱体旋转到…

网络攻击原理及过程

网络攻击原理表 攻击者 内容 攻击访问 攻击效果 攻击意图 黑客 挑战 间谍 用户命令 破坏信息 好奇 恐怖主义者 脚本或程序 本地访问 信息泄密 获取情报 公司职员 自治主体 远程访问 窃取服务 经济利益 职业犯罪分子 电磁泄露 拒绝服务 恐怖事…

CSS3 3D 转换

CSS3 3D 转换 CSS3 3D 转换是一种强大的技术,它允许开发者创建出令人印象深刻的3D视觉效果,而无需复杂的JavaScript或第三方库。通过使用CSS3的3D转换功能,设计师可以轻松地将元素旋转、倾斜、移动或缩放,以创建出深度和透视感。在本文中,我们将探讨CSS3 3D转换的基础知识…

python 压力测试脚本

需求&#xff1a; 生成一个12位不重复的随机数将随机数赋值给Json 串中的 orderCode字段将Json用ECB 指定 key为bJXQezYtR4ZSNK4p进行加密并作为值传给{ “data”: “” }设置每秒30个并发持续1分钟调用接口接口输出测试测试报告 代码示例 import json import random import…

鸿蒙验证码,鸿蒙认证服务验证码,鸿蒙云存储上传图片

1、在entry / oh-package.json5目录下&#xff0c;增加依赖&#xff1a; "dependencies": {hw-agconnect/cloud: "^1.0.0",hw-agconnect/hmcore: "^1.0.0",hw-agconnect/auth-component: "^1.0.0",long: ^5.2.1} 整体效果 {"…

vue.js - 看板娘 Live2d

文中的资源文件在这里&#xff1a;我的资源中&#xff0c;打好包了已经&#xff0c;地址&#xff1a;live2d资源 1、在项目的 src/assets 文件夹中&#xff0c;添加 live2d 的资源文件 2、在 src/components 文件中&#xff0c;编写 live2d的index.vue组件 3、在 App.vue 中…

技术文档索引

1.Python爬虫之BeautifulSoup的文章链接 2.Python爬虫之正则表达式

【重点】人工智能大语言模型技术发展研究报告2024|附下载

人工智能作为引领新一轮科技产业革命的战略性技术和新质生产力重要驱动力&#xff0c;正在引发经济、社会、文化等领域的变革和重塑。 2023 年以来&#xff0c;以ChatGPT、GPT-4 为代表的大模型技术的出台&#xff0c;因其强大的内容生成及多轮对话能力&#xff0c;引发全球新…

MYSQL————数据库的约束

1.约束类型 1.not null&#xff1a;指示某列不能存储null值 2.unique&#xff1a;保证某列的每行必须有唯一值 3.default&#xff1a;规定没有给列赋值时的默认值 4.primary key&#xff1a;not null和unique的结合。确保某列&#xff08;或两个或多个列的结合&#xff09;有唯…

《中国科技论坛》

《中国科技论坛》杂志   刊名&#xff1a;中国科技论坛/Forum on Science and Technology in China 主办&#xff1a;中国科学技术发展战略研究院 编辑出版&#xff1a;中国科技论坛杂志社 创刊&#xff1a;1985 刊期/版面&#xff1a;月刊&#xff0c;大16开 刊号&#…

聊聊最近很火的后端即服务

最近&#xff0c;你可能经常听到“后端即服务”&#xff08;Backend as a Service, BaaS&#xff09;这个词。不论是在技术论坛上&#xff0c;还是在开发者社区&#xff0c;BaaS都成了大家讨论的热点。究竟是什么让这个概念如此火爆&#xff1f;今天我们就来聊聊这个话题&#…

TCP粘包和抓包

在 TCP 套接字中&#xff0c;发送和接收缓冲区用于暂存数据&#xff0c;以确保数据的可靠传输。具体来说&#xff0c;TCP 的 socket 收发缓冲区的主要特点和概念如下&#xff1a; 1. 发送缓冲区&#xff08;Send Buffer&#xff09; 定义: 发送缓冲区用于存储待发送的数据。应…

大模型从入门到精通——词向量及知识库介绍

词向量及知识库介绍 1.词向量 1.1 什么是词向量 词向量是一种将单词表示为实数向量的方式。每个单词通过一个高维向量来表示&#xff0c;向量的每一维都是一个实数&#xff0c;这些向量通常位于一个高维空间中。词向量的目标是将语义相似的单词映射到相邻的向量空间中&#…