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

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">
          <i
            title="缩小"
            class="iconfont icon-segi-icon-minus"
            style="font-size: 14px"
            @click="toCollapse"
          ></i>
          <i
            title="关闭"
            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">
        <i
          title="放大"
          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.mfbz.cn/a/606906.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

IDEA远程连接Docker服务

1.确保你的服务器已经安装docker docker安装步骤可查看&#xff1a;CentOS 9 (stream) 安装 Docker 2.安装完docker后开启远程连接 默认配置下&#xff0c;Docker daemon只能响应来自本地Host的客户端请求。如果要允许远程客户端请求&#xff0c;需要在配置文件中打开TCP监听…

【数据结构】栈(Stack)和队列(Queue)

文章目录 栈一、栈的概念及结构二、栈的特点三、栈的实现1.初始化栈2.判断栈空3.入栈4.出栈5.取栈顶元素6.栈的元素个数7.销毁 队列一、队列的概念及结构二、队列的特点三、队列的实现1.初始化2.入队3.出队4.判断队空5.取队头元素6.取队尾元素 总结 栈 一、栈的概念及结构 栈…

k8s 理论知识基本介绍

目录 一 k8s 理论前言 &#xff08;一&#xff09;微服务是什么 1&#xff0c;应用场景 2&#xff0c;API 是什么 &#xff08;二&#xff09;&#xff0c;微服务 如何做版本迭代 1. Docker镜像构建 2. 版本标记 3. Docker Registry 4. 环境一致性 5. 滚动更新…

26 | 备库为什么会延迟好几个小时?

在官方的 5.6 版本之前,MySQL 只支持单线程复制,由此在主库并发高、TPS 高时就会出现严重的主备延迟问题。 coordinator 就是原来的 sql_thread, 不过现在它不再直接更新数据了,只负责读取中转日志和分发事务。真正更新日志的,变成了 worker 线程。而 work 线程的个数,就是…

今日刷三题(day12):兑换零钱(一)+最长回文子串+编辑距离(一)

题目一&#xff1a;兑换零钱&#xff08;一&#xff09; 题目描述&#xff1a; 给定数组coins&#xff0c;coins中所有的值都为正整数且不重复。每个值代表一种面值的货币&#xff0c;每种面值的货币可以使用任意张&#xff0c;再给定一个aim&#xff0c;代表要找的钱数&…

单位圆内的正交向量多项式,第一部分:由Zernike多项式的梯度导出的基组

clear all; close all; clc; %% I1=double(imread(E:\zhenlmailcom-E8E745\华为家庭存\image\imgs\right\0.bmp)); I2=double(imread(E:\zhenlmailcom-E8E745\华为家庭存储\.法\image\imgs\right\1.bmp)); I3=double(imread(E:\zhenlmailcom-E8E745\华为家庭存储\.p\image\imgs…

学习torchmd分子动力学模拟

TorchMD打算提供一种简单易用的API&#xff0c;用于使用PyTorch进行分子动力学。这使研究人员能够更快地进行力场开发研究&#xff0c;并以PyTorch的简单性和强大性将神经网络潜力无缝集成到动力学中。 TorchMD使用与经典MD代码&#xff08;如ACEMD&#xff09;一致的化学单位&…

实在Agent智能体:引领智能自动化新纪元

在数字化转型的浪潮中&#xff0c;实在智能科技有限公司凭借其前沿技术&#xff0c;推出了实在Agent智能体——一款革命性的超自动化智能体。它不仅代表了人工智能技术的新高度&#xff0c;更预示着未来工作方式的变革。 什么是实在Agent智能体&#xff1f; 实在Agent智能体是…

《Fundamentals of Power Electronics》——状态空间平均法

文献中出现了许多交流变换器建模技术&#xff0c;包括电流注入法、电路平均法和状态空间平均法。尽管给定方法的支持者可能更喜欢用特定形式表示最终结果&#xff0c;但几乎所有方法的最终结果都是等效的。所有人都会赞同&#xff0c;平均和小信号线性化是PWM变换器建模的关键步…

云动态摘要 2024-05-06

给您带来云厂商的最新动态&#xff0c;最新产品资讯和最新优惠更新。 最新优惠与活动 [免费试用]即刻畅享自研SaaS产品 腾讯云 2024-04-25 涵盖办公协同、营销拓客、上云安全保障、数据分析处理等多场景 云服务器ECS试用产品续用 阿里云 2024-04-14 云服务器ECS试用产品续用…

用得助全媒体呼叫中心,让AI落到实处帮品牌做营销

怎么让人工智能落到实处的帮助到我们&#xff1f;我们今天来讲讲中关村科金得助全媒体呼叫中心是怎么让AI帮品牌。 这次聊的案例是知名的护肤品牌&#xff0c;该品牌在中国功能性护肤品市场占有率达到20.5%&#xff0c;这么高的市场占有率客户的咨询量也是非常庞大的&#xff0…

MAC M1 配置 Git SSH

背景 换了新笔记本&#xff0c;本地想要克隆github 上的项目需要配置ssh 公钥到自己的github账户中&#xff0c;否则使用ssh 地址克隆会报错&#xff0c;如下。 gitgithub.com: Permission denied (publickey). fatal: Could not read from remote repository.操作 1. 生成s…

探索大型语言模型(LLM)的世界

​ 引言 大型语言模型&#xff08;LLM&#xff09;作为人工智能领域的前沿技术&#xff0c;正在重塑我们与机器的交流方式&#xff0c;在医疗、金融、技术等多个行业领域中发挥着重要作用。本文将从技术角度深入分析LLM的工作原理&#xff0c;探讨其在不同领域的应用&#xff0…

安卓使用Fiddler抓包 2024

简介 最近试了一下安卓使用fiddler 抓包&#xff0c;发现https包基本都会丢失。原因是Anandroid 7版本针对ssl安全性做了加强&#xff0c;不认可用户的证书。我们要做的就是把fiddler导出的证书进过处理后放置到系统证书目录下面&#xff0c;这样才能抓包https请求。 这里使用…

【Anaconda】升级Anaconda Navigator提示JSONDecoderError,删除.condarc文件后搞定

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、报错&#xff1a;JSONDecoderError二、错误原因三、解决问题总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 时间长未升级Ana…

AI 绘画神器 Fooocus 本地部署指南:简介、硬件要求、部署步骤、界面介绍

本文收录于《AI绘画从入门到精通》专栏&#xff0c;专栏总目录&#xff1a;点这里&#xff0c;订阅后可阅读专栏内所有文章。 大家好&#xff0c;我是水滴~~ 随着人工智能技术的飞速发展&#xff0c;AI 绘画逐渐成为创意领域的新宠。Fooocus 作为一款免费开源的 AI 绘画工具&am…

窜货溯源采买的目的

当品牌遇到窜货时&#xff0c;不管是线上还是线下渠道&#xff0c;快速的治理方法&#xff0c;就是找到窜货源头&#xff0c;对源头进行打击&#xff0c;这里面有一步很关键的操作便是买货&#xff0c;将货品买回后做溯源&#xff0c;通过产品本身或者外包装上的条码&#xff0…

【Java orm 框架比较】十 新增hammer_sql_db 框架对比

迁移到&#xff08;https://gitee.com/wujiawei1207537021/spring-orm-integration-compare&#xff09; orm框架使用性能比较 比较mybatis-plus、lazy、sqltoy、mybatis-flex、easy-query、mybatis-mp、jpa、dbvisitor、beetlsql、dream_orm、wood、hammer_sql_db 操作数据 …

[uniapp 地图组件] 小坑:translateMarker的回调函数,会调用2次

大概率是因为旋转和移动是两个动画&#xff0c;动画结束后都会分别调用此函数 即使你配置了 【不旋转】它还是会调用两次&#xff0c; 所以此处应该是官方的bug

未来娱乐新地标?气膜球幕影院的多维体验—轻空间

在中国&#xff0c;一座独特的娱乐场所正在崭露头角&#xff1a;气膜球幕影院。这个融合了气膜建筑与激光投影技术的创新场所&#xff0c;不仅令人惊叹&#xff0c;更带来了前所未有的科幻娱乐体验。让我们一起探索这个未来的娱乐空间&#xff0c;感受其中的多维魅力。 现场演出…
最新文章