封装一个可以最小化和展开的弹窗组件

gl-dialog

大概思路:
在弹窗组件内部引入gl-dialog-collapse,这个组件主要用于存储已经被最小化的弹窗(基础数据)
弹窗内部的数据如何在父组件拿到是通过作用域插槽来实现的
gl-dialog接收一个tempData这个数据会在内部被记录下来,然后通过插槽的形式传递给父组件,供父组件使用
在这里插入图片描述

<template><div class="gl-dialog" ref="dialogRef"><el-dialog:close-on-click-modal="false"v-bind="$attrs":visible.sync="selfVisible":show-close="false"><div class="dialog-header" slot="title"><div class="left-title">{{ currentData.dialogTitle }}</div><div class="right-icon"><ititle="缩小"class="iconfont icon-segi-icon-minus"style="font-size: 14px"@click="toCollapse"></i><ititle="关闭"class="iconfont icon-Close"style="font-size: 14px;font-weight: bold;"@click="closeDialog"></i></div></div><slot :tempData="currentData"></slot><footer><slot name="footer" :tempData="currentData" /></footer></el-dialog><gl-dialog-collapse :dialogList="dialogList"></gl-dialog-collapse></div>
</template><script>
import _ from "lodash";
export default {name: "gl-dialog",props: {visible: {type: Boolean,default: () => false,},title: String,type: {type: String,default: () => "default",},tempData: Object,},data() {return {ddd: "okok",dialogList: [],currentData: {},count: 0,isExpand: false,// dialogId: "",};},computed: {dialogId() {return this.tempData.dialogTitle + this.count;},selfVisible: {get() {return this.visible;},set(value) {this.$emit("update:visible", value);},},},watch: {visible(N) {if (N) {if (!this.isExpand) {this.currentData = _.cloneDeep(this.tempData);this.currentData.dialogTitle = this.title;this.currentData.dialogId = this.dialogId;} else {this.count++;}}},},methods: {toCollapse() {const targetIndex = this.dialogList.findIndex((item) => {const { dialogId } = this.currentData;return dialogId == item.dialogId;});const isExist = targetIndex >= 0;if (!isExist) {this.dialogList.push({type: this.type,title: this.currentData.dialogTitle,dialogId: this.dialogId,tempData: this.currentData,expandCallBack: (tempData) => {this.isExpand = true;this.currentData = tempData;this.currentData.dialogId = tempData.dialogId;this.selfVisible = true;},});this.count++;}this.isExpand = false;this.selfVisible = false;},closeDialog() {this.isExpand = false;this.selfVisible = false;if (!this.dialogList.length) return;const targetIndex = this.dialogList.findIndex((item) => {const dialogId = this.isExpand? this.currentData.dialogId: this.dialogId;return dialogId == item.dialogId;});if (targetIndex >= 0) {this.dialogList.splice(targetIndex, 1);}},},
};
</script><style lang="scss" scoped>
.dialog-header {display: flex;align-items: center;justify-content: space-between;
}
// ::v-deep .dialog-footer {
//   text-align: right!important;
// }
.iconfont {cursor: pointer;
}
footer {text-align: right;
}
</style>

gl-dialog-collapse.vue

<template><div class="gl-dialog-collapse"><div class="collapse-item" v-for="(item, index) in dialogList" :key="index"><div class="title">{{ item.title }}</div><div class="right-icons"><ititle="放大"class="iconfont icon-icf_full_screen_arrow"@click="toExpand(item)"></i><i title="关闭" class="iconfont icon-Close" @click="closeDialog"></i></div></div></div>
</template><script>
export default {name: "gl-dialog-collapse",props: {dialogList: {type: Array,default: [],},},methods: {toExpand(item) {const { expandCallBack, tempData } = item;expandCallBack(tempData);this.closeDialog(item);},closeDialog(item) {const { dialogId } = item;const targetIndex = this.dialogList.findIndex((item) => item.dialogId == dialogId);this.dialogList.splice(targetIndex, 1);},},
};
</script><style lang="scss" scoped>
.gl-dialog-collapse {display: flex;column-gap: 5px;position: fixed;left: 201px;bottom: 0px;
}
.collapse-item {padding: 5px 10px;display: flex;align-items: center;column-gap: 20px;border: 1px solid #ccc;background-color: #fff;.title {font-size: 14px;}
}
.right-icons {i {cursor: pointer;font-size: 16px;}
}
</style>

实现效果:
在这里插入图片描述
在这里插入图片描述
每个最小化的弹窗内部数据都是独立的,因为gl-dialog-collapse内部维护了一个已经被折叠的弹窗数组。
内部的数据结构:

{type: this.type,title: this.currentData.dialogTitle,dialogId: this.dialogId,tempData: this.currentData,expandCallBack: (tempData) => {this.isExpand = true;this.currentData = tempData;this.currentData.dialogId = tempData.dialogId;this.selfVisible = true;},}

dialogId用于记录唯一弹窗,方便回显数据,以及关闭目标弹窗

反思:当时考虑用cloneNode来实现弹窗的复制,但是考虑到vue里面是通过数据来驱动视图,能够成功复制弹窗,但是里面的交互会失效,所以感觉这种方案会很复杂,所以放弃。中途参考过layui弹窗最小化的实现方式,发现是对节点进行克隆,所以每最小化一个弹窗就会多产生一个节点。

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

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

相关文章

salmon使用体验

文章目录 salmon转录本定量brief模式一&#xff1a;fastq作为输入文件需要特别注意得地方 模式二&#xff1a; bam文件作为输入 salmon转录本定量 brief 第一点是&#xff0c;通常说的转录组分析其中有一项是转录本定量&#xff0c;这是一个很trick的说话&#xff0c;说成定量…

代码随想录算法训练营第四十二天| 01背包问题(二维、一维)、416.分割等和子集

系列文章目录 目录 系列文章目录动态规划&#xff1a;01背包理论基础①二维数组②一维数组&#xff08;滚动数组&#xff09; 416. 分割等和子集①回溯法&#xff08;超时&#xff09;②动态规划&#xff08;01背包&#xff09;未剪枝版剪枝版 动态规划&#xff1a;01背包理论基…

基于Vue3与ElementUI Plus酷企秀可视化设计器中的创新应用

一、引言 随着科技的快速发展&#xff0c;前端技术已经从简单的网页呈现进化到了复杂的数据可视化、互动体验和跨平台应用的构建。酷企秀可视化设计器作为一个集成了多种前端技术的创新平台&#xff0c;不仅为企业提供了全方位的数字化展示解决方案&#xff0c;还在多个行业领…

Java实现NFS文件上传、下载和读取功能的工具类

Java实现NFS文件上传、下载和读取功能的工具类 引言&#xff1a;代码示例一、准备工作二、工具类设计与核心方法三、异常处理与性能优化四、总结 引言&#xff1a; NFS&#xff08;Network File System&#xff09;广泛应用于分布式环境的情况下&#xff0c;这里介绍使用Java工…

SRC上分秘诀+实战挖掘+挖洞技巧+新手上路+详细讲解

SRC马上到来 可能有些好兄弟们还没有头绪 只会做一些靶场 并没有什么实战经验 所以这篇文章给大家分享一下我挖洞2个月的经验分享 适合新手上路 如何找站&#xff1f; 谷歌搜索 谷歌搜索 谷歌搜索 SQL注入XSS所有漏洞 inurl:.php?idxx 公司inurl:.asp?idxx 公司inurl:.jsp?…

【考研数学】强化《660》和《880》先做哪个?

880和660一般在强化阶段做 这两本习题各自的特点是&#xff1a; 660题是专门训练客观题的&#xff0c;难度较大&#xff0c;对于基础知识点的考察比较深入&#xff0c;如果你的基础不好&#xff0c;去做660题很有可能被打击到&#xff0c;这个时候不要担心&#xff0c;很正常&a…

「AIGC」Agent AI智能体的未来:技术、伦理与经济的交汇点

Agent AI智能体&#xff0c;作为人工智能领域的前沿技术&#xff0c;正逐渐渗透到社会的各个层面。随着技术的不断进步&#xff0c;Agent AI智能体在提高效率、促进创新、甚至重塑社会结构方面展现出巨大潜力。然而&#xff0c;这也带来了一系列挑战&#xff0c;包括技术发展、…

cf240-B-Mashmokh and ACM DP

https://codeforces.com/contest/414/problem/B 题意: 在[1,n]范围内 构造出一个长度为k的数组 使得a[i1]%a[i]0 求出数组的个数%1e97 思考: 在一开始,会去想这是一道数学题,似乎得出某个式子便可以得出结果,因此就开始一个一个的去构造尝试,当构造了几个样例后,也许会发现…

Mysql基础篇(一)Mysql概述

目录 基本概念 数据库(DataBase,DB) 数据库的定义 数据库的分类 数据库管理系统(DataBase Management System,DBMS) SQL(Structured Query Language) Mysql Mysql数据模型 下载安装Mysql 基本概念 数据库(DataBase,DB) 数据库的定义 按照数据结构来组织、存储和管理数…

Springboot整合Minio,2024版教程

Springboot整合Minio&#xff0c;2024版教程 介绍安装方式代码pomymlconfigMinioService 推荐文章 介绍 CSDN里面找资料真的是垃圾堆里刨食吃。优质作者和内容非常少&#xff0c;最近还出现了评论下方打广告的&#xff0c;粉丝上w&#xff0c;文章内容质量主打一个抄袭&#xf…

java报错:使用mybatis plus查询一个只返回一条数据的sql,却报错返回了1000多条

今天遇到一个问题 系统线上问题&#xff0c;经常出现这样的问题&#xff0c;刚重启系统时不报错了&#xff0c;可是运行一段时间又会出现。sql已经写了limit 1&#xff0c;mybatis的debug日志也返回total为1&#xff0c;可是却报错返回了1805条数据 乍一看&#xff0c;感觉太不…

《21天学通C++》(第十四章) 宏和模板介绍(2)

相较于宏&#xff0c;C更推荐使用模板编程&#xff0c;因为它们提供了更好的类型安全、更清晰的语法和更易于调试的代码 1.模板函数 语法 template <typename T> void function(T param) {// 函数体&#xff0c;使用T作为类型参数 }例子 #include <iostream> us…

汽车之家,如何在“以旧换新”浪潮中大展拳脚?

北京车展刚刚落幕&#xff0c;两重利好正主导汽车市场持续升温&#xff1a;新能源渗透率首破50%&#xff0c;以及以旧换新详细政策进入落地期。 图源&#xff1a;中国政府网 在政策的有力指引下&#xff0c;汽车产业链的各个环节正经历着一场深刻的“连锁反应”。在以旧换新的…

Python运维之多线程!!

一、多线程 二、多线程编程之threading模块 2.1、使用threading进行多线程操作有两种方法&#xff1a; 三、多线程同步之Lock&#xff08;互斥锁&#xff09; 四、多线程同步之Semaphore&#xff08;信号量&#xff09; 五、多线程同步之Condition 六、多线程同步之Event…

CSS和JavaScript

CSS 在html中引入CSS 我们需要先在该项目先建立css文件 html引入CSS,在<head></head>中添加<link>标签 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" co…

mac 本地使用docker 运行es,kibana

1.下载 m芯片一些版本不支持.踩过坑.翻看官网才知道只有部分镜像支持m芯片 https://hub.docker.com/添加链接描述 docker pull elasticsearch:7.17.21 docker pull kibana:7.17.21镜像已经下载下来了 2.创建文件映射-挂载 /Users/lin/dev/dockerMsg 其中lin是自己的用户名…

关于线程池,它的扩展问题你知道吗?(自己总结)

专门想一下为什么线程池不用Excutors&#xff0c;之前的印象是错的&#xff0c;居然还拿来面试里讲&#xff0c;惭愧&#xff0c;这里暂时整理俩小问题&#xff0c;其他的后续可能会更新。。 线程池是创建的越大越好嘛 #线程池创建的越大越好吗 Tip&#xff1a;2024-04-10 更…

本地搭建hydra服务用go以验证oidc流程

目录 1、docker搭建hydra&#xff0c;环境配置&#xff1a; 2、搭建完成后服务调用&#xff1a; 2.1保证服务正常启动&#xff1a; 2.2 通过postman调用&#xff0c;获取client_id&#xff1a; 2.3 通过client_id&#xff0c;实现oauth2/auth调用 3. 通过go语言实现oidc验…

【qt】容器的用法

容器目录 一.QVertor1.应用场景2.增加数据3.删除数据4.修改数据5.查询数据6.是否包含7.数据个数8.交换数据9.移动数据10.嵌套使用 二.QList1.应用场景2.QStringList 三.QLinkedList1.应用场景2.特殊点3.用迭代器来变量 四.QStack1.应用场景2.基本用法 五.QQueue1.应用场景2.基本…

【前端每日一题】day2

用JS写一个快速排序算法 function quickSort(arr) {if (arr.length < 1) {return arr;}const pivot arr[Math.floor(arr.length / 2)];const left [];const right [];for (let i 0; i < arr.length; i) {if (i Math.floor(arr.length / 2)) {continue; // Skip piv…