Element plus 低版本弹窗组件添加拖拽功能
在使用element plus 弹窗组件el-dialog 的时候,由于自己组件库版本过低,所以就会缺失某些功能,比如弹窗组件的可拖拽功能。因为某些原因element plus 组件库又不能升级,所以此时就需要自己为弹窗组件添加拖拽功能。共分为一下四个步骤
- 在全局状态管理中添加两个属性,dialogDom 用于保存弹窗dom,visible, 用于保存弹窗组件的props.visible便于插件根据弹窗的开关状态进行事件的绑定和解除。
- 在自己的弹窗组件中的el-dialog 的标签中添加ref,并监听props.visible 。当弹窗打开时将弹窗的dom,及props.visible,存入全局状态管理的新增属性中。
-
自定义插件,编写拖拽功能
插件中使用watch,只能执行一次,并不能监听store.visible 的改变。所以使用Object.defineProperty,监听store.visible
- 安装插件。app.use();
/** @Description:弹窗过拽插件* @Author: zhangyuqi* @Date: 2024-05-27 11:01:01* @LastEditors: zhangyuqi* @LastEditTime: 2024-05-27 17:41:00* @FilePath: \idata-micro\src\plugins\dialog-drag.ts*/
import { App, reactive, ref } from 'vue';
import dataReportStore from '@/store/modules/data-report';export default {install(app:App) {let dialogVisible = dataReportStore.state.visible as Boolean;const myDialogDom = ref <any>(dataReportStore.state.dialogDom);const state = reactive({active: false,top: 0,left: 0,right: 0,bottom: 0,currentX: 0,currentY: 0,initialX: 0,initialY: 0,transformX: 0,transformY: 0,});// 鼠标进入触发方法const mouseEnter = (event:MouseEvent) => {// 鼠标进入修改弹窗元素鼠标形状if (myDialogDom.value) {// eslint-disable-next-line no-param-reassignmyDialogDom.value.firstElementChild.style.cursor = 'move';}};// 鼠标按下触发方法const mouseDown = (event:MouseEvent) => {// 鼠标进入修改弹窗元素鼠标形状if (myDialogDom.value) {event.preventDefault();// 获取元素宽高const { left, right, top, bottom } = myDialogDom.value.getBoundingClientRect();state.top = top;state.left = left;state.right = right;state.bottom = bottom;if (myDialogDom.value?.style.transform) {// 此时弹窗已经被拖拽过,存在偏移量,所计算的值应在当前偏移量上进行累加const str = myDialogDom.value.style.transform;const regExp = /-?\d+(?:\.\d+)?/g;const result = str.match(regExp) as any;state.transformX = Number(result[0]);state.transformY = Number(result[1]);state.bottom -= state.transformY;state.left -= state.transformX;state.right -= state.transformX;state.top -= state.transformY;}// eslint-disable-next-line no-param-reassignstate.initialX = event.clientX;state.initialY = event.clientY;// }state.active = true;}};// 鼠标按下触发方法const mouseUp = () => {// 鼠标进入修改弹窗元素鼠标形状if (myDialogDom.value) {state.active = false;state.top = 0;state.bottom = 0;state.left = 0;state.right = 0;state.initialX = 0;state.initialY = 0;state.currentX = 0;state.currentY = 0;state.transformX = 0;state.transformY = 0;}};// 鼠标按下触发方法const mouseMove = (event:MouseEvent) => {// 鼠标进入修改弹窗元素鼠标形状if (state.active) {event.preventDefault();state.currentX = event.clientX - state.initialX + state.transformX;state.currentY = event.clientY - state.initialY + state.transformY;// 上边界if (state.currentY <= -state.top) state.currentY = -state.top;// 左边界if (state.currentX <= -state.left) state.currentX = -state.left;// 下边界if (state.currentY >= (window.innerHeight - state.bottom)) state.currentY = window.innerHeight - state.bottom;// 右边界if (state.currentX >= (window.innerWidth - state.right)) state.currentX = window.innerWidth - state.right;// eslint-disable-next-line no-param-reassignmyDialogDom.value.style.transform = `translate(${state.currentX}px, ${state.currentY}px)`;}};// 监听器函数const watcher = (newVal:Boolean) => {if (newVal) {myDialogDom.value = dataReportStore.state.dialogDom;if (myDialogDom.value) {myDialogDom.value.firstElementChild.addEventListener('mouseenter', mouseEnter);myDialogDom.value.firstElementChild.addEventListener('mousedown', mouseDown);myDialogDom.value.firstElementChild.addEventListener('mouseup', mouseUp);document.addEventListener('mouseup', mouseUp);document.addEventListener('mousemove', mouseMove);}// 当鼠标移入的时候,更改鼠标形态// 当鼠标按下时} else {const { dialogDom } = dataReportStore.state as any;if (dialogDom) {myDialogDom.value.firstElementChild.removeEventListener('mouseenter', mouseEnter);myDialogDom.value.firstElementChild.removeEventListener('mousedown', mouseDown);myDialogDom.value.firstElementChild.removeEventListener('mouseup', mouseUp);document.removeEventListener('mouseup', mouseUp);document.removeEventListener('mousemove', mouseMove);}}};Object.defineProperty(dataReportStore.state, 'visible', {get() {return dialogVisible;},set(val:Boolean) {dialogVisible = val;watcher(val);},});},
};
注释:
- mouseenter,mousedown,mouseup方法都绑定在弹窗的header 部分的dom元素上。因为事件触发需要使用event.preventDefault()来清楚鼠标默认事件 。如果这三个鼠标事件绑定在弹窗整体元素上,调用event.preventDefault()之后,弹窗内的输入框等元素的功能就无法正常使用了。
- mouseup,mousemove事件绑定在document上,因为当鼠标拖拽弹窗在窗口边缘时,只要不松手,拖拽依然在窗口内是有效果的。如果没有绑定到document上,如果将弹窗拖拽至窗口上边缘,此时鼠标移出窗口范围至浏览器边框时,松手,再移会窗口。此时弹窗仍然会根据鼠标进行移动,这样是不对的。
相关文章:
Element plus 低版本弹窗组件添加拖拽功能
在使用element plus 弹窗组件el-dialog 的时候,由于自己组件库版本过低,所以就会缺失某些功能,比如弹窗组件的可拖拽功能。因为某些原因element plus 组件库又不能升级,所以此时就需要自己为弹窗组件添加拖拽功能。共分为一下四个…...

计算机组成原理易混淆知识点总结(持续更新)
目录 1.机器字长,存储字长与指令字长 2.指令周期,机器周期,时钟周期 3.CPI,IPS,MIPS 4.翻译程序和汇编程序 5.计算机体系结构和计算机组成的区别和联系 6.基准程序执行得越快说明机器的性能越好吗? 1.机器字长,存储字长与指令字长 不同的机器三者…...

【STM32踩坑】HAL固件库版本过高导致烧录后无法运行问题
问题引入 目前STM32CUBEMX已经更新到了6.11版本,对应的固件库也一直在更新; 以STM32F1库为例,目前最新的库对应版本为1.8.5 但是我们会发现,如果直接使用1.8.5版本的固件库生成HAL源码后,烧录是可以烧录,但…...
芯片丝印反查
芯片丝印反查网 - IC芯片丝印,IC芯片代码,IC芯片印字,IC芯片顶标,SMD code,marking code,top mark芯查查-电子信息产业数据引擎 ic/芯片丝印反查网-芯查查...

C语言之指针详解(5)(含有易错笔试题)
文章目录 一、sizeof和strlen的对比1.1 sizeof1.2 strlen1.3 sizeof 和 strlen 的对比 二、数组和指针笔试题2.1 一维数组2.2 字符数组2.3 二维数组 三、指针运算笔试题3.1 题目13.2 题目23.3 题目33.4 题目43.5 题目53.6 题目63.7 题目7 一、sizeof和strlen的对比 有一个很神…...

discuzX2.5的使用心得 札记一
从开始接受php论坛的开发任务,对php感兴趣的我开始迷恋上discuz这个产品了, 像戴志康这样的创新人才,是我们这代人的骄傲和学习的榜样 应该是了解一下,啥事discuzX2.5,百度看一下 discuz x2.5_百度百科 看完百度词条…...

【Python】 探索Django框架的高并发处理能力
基本原理 Django是一个高级的Python Web框架,它鼓励快速开发和干净、实用的设计。Django遵循MVC(模型-视图-控制器)设计模式,提供了一个全栈式的解决方案,使得开发者能够快速构建功能丰富的Web应用。Django的高并发处…...
C-数据结构-平横二叉树
平衡二叉树(Balanced Binary Tree)是一种二叉树,其中任意节点的两棵子树的高度差不超过 1。也可以说是一棵空树或者左右子树高度差不超过 1 的二叉树。 特点和性质 高度平衡:平衡二叉树是一种高度平衡的二叉树,任意节…...
算法训练营day41
动态规划理论基础(主要就是确定动态规划的几个步骤) 题目1:509. 斐波那契数 - 力扣(LeetCode) class Solution { public:int fib(int n) {if(n 0) return 0;if(n 1) return 1;int dp1 0;int dp2 1;int dp3 0;fo…...

cesium开发实例分享
反正 cesium 看到的效果几乎都有...

字符串和字符串函数(1)
前言: 字符串在C语言中比较特别,没有单另的字符串类型,想要初始化字符串必须用字符变量的数组初始化,但是在C语言标准库函数中提供了大量能对字符串进行修改的函数,比如说可以实现字符串的的拷贝,字符串的追…...

基于springboot+vue的班级综合测评管理系统
开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:…...

蓝海项目揭秘:跨境选品师的崛起与挑战
随着全球化贸易的日益深入和电子商务的蓬勃发展,跨境选品师这一新兴职业逐渐走进人们的视野。跨境选品师,顾名思义,就是专门负责为跨境电商平台挑选和推荐适合海外市场的商品的专业人士。那么,跨境选品师这一职业能否被视为一个蓝…...

酷黑简洁大气体育直播自适应模板赛事直播门户网站源码
源码名称:酷黑简洁大气体育直播自适应模板赛事直播门户网站源码 开发环境:帝国cms 7.5 安装环境:phpmysql 支持PC与手机端同步生成html(多端同步生成插件) 带软件采集,可以挂着自动采集发布,无…...

2024年电工杯高校数学建模竞赛(B题) 建模解析| 大学生平衡膳食食谱的优化设计
问题重述及方法概述 问题1:膳食食谱的营养分析评价及调整 数学方法:线性规划模型、营养素评价模型、比较分析 可视化数据图:营养素含量表、营养素摄入量对比图、营养素缺乏情况图 问题2:基于附件3的日平衡膳食食谱的优化设计 数…...

学习编程对英语要求高吗?
学习编程并不一定需要高深的英语水平。我这里有一套编程入门教程,不仅包含了详细的视频讲解,项目实战。如果你渴望学习编程,不妨点个关注,给个评论222,私信22,我在后台发给你。 虽然一些编程资源和文档可能…...

使用 Django 和 RabbitMQ 构建高效的消息队列系统
文章目录 RabbitMQ 简介Django 中使用 RabbitMQ总结与拓展 在现代的 Web 应用程序开发中,构建一个高效的消息队列系统变得越来越重要。使用消息队列可以帮助我们解耦系统中不同模块的任务,并提高系统的性能和可扩展性。本文将介绍如何结合 Django 和 Rab…...

Pycharm常见问题1
问题: ValueError at /user/users/ The view user.views.get_users didnt return an HttpResponse object. It returned None instead. 问题分析: 视图user.views.get_users未返回HttpResponse对象,它返回值为None。也就是说在视图文件没有…...

开发一个comfyui的自定义节点
文章目录 目标功能开发环境comfyui自定义节点的实现原理仓库地址完整代码目标功能 开发一个comfyui的自定义节点,该节点的功能是:可以对comfyui工作流中最终输出的图像添加一些自定义文案,且可以指定文案在图像上的位置、文案的字体样式、字体大小、字体颜色等。最终效果如…...
Prime算法构造最小生成树(加点法)
一、算法逻辑 想要轻松形象理解Prime的算法逻辑,视频肯定比图文好。 小编看过很多求相关的教学视频,这里选出一个我认为最好理解的这一款安利给大家。 因为他不仅讲解细致,而且还配合了动画演示,可以说把一个抽象的东西讲的非常…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...

RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...

el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看
文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...