当前位置: 首页 > news >正文

Element plus 低版本弹窗组件添加拖拽功能

        在使用element plus 弹窗组件el-dialog 的时候,由于自己组件库版本过低,所以就会缺失某些功能,比如弹窗组件的可拖拽功能。因为某些原因element plus 组件库又不能升级,所以此时就需要自己为弹窗组件添加拖拽功能。共分为一下四个步骤

  1. 在全局状态管理中添加两个属性,dialogDom 用于保存弹窗dom,visible, 用于保存弹窗组件的props.visible便于插件根据弹窗的开关状态进行事件的绑定和解除。
  2. 在自己的弹窗组件中的el-dialog 的标签中添加ref,并监听props.visible 。当弹窗打开时将弹窗的dom,及props.visible,存入全局状态管理的新增属性中。
  3. 自定义插件,编写拖拽功能

    插件中使用watch,只能执行一次,并不能监听store.visible 的改变。所以使用Object.defineProperty,监听store.visible

  4. 安装插件。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);},});},
};

注释:

  1. mouseenter,mousedown,mouseup方法都绑定在弹窗的header 部分的dom元素上。因为事件触发需要使用event.preventDefault()来清楚鼠标默认事件 。如果这三个鼠标事件绑定在弹窗整体元素上,调用event.preventDefault()之后,弹窗内的输入框等元素的功能就无法正常使用了。
  2. mouseup,mousemove事件绑定在document上,因为当鼠标拖拽弹窗在窗口边缘时,只要不松手,拖拽依然在窗口内是有效果的。如果没有绑定到document上,如果将弹窗拖拽至窗口上边缘,此时鼠标移出窗口范围至浏览器边框时,松手,再移会窗口。此时弹窗仍然会根据鼠标进行移动,这样是不对的。

相关文章:

Element plus 低版本弹窗组件添加拖拽功能

在使用element plus 弹窗组件el-dialog 的时候&#xff0c;由于自己组件库版本过低&#xff0c;所以就会缺失某些功能&#xff0c;比如弹窗组件的可拖拽功能。因为某些原因element plus 组件库又不能升级&#xff0c;所以此时就需要自己为弹窗组件添加拖拽功能。共分为一下四个…...

计算机组成原理易混淆知识点总结(持续更新)

目录 1.机器字长&#xff0c;存储字长与指令字长 2.指令周期,机器周期,时钟周期 3.CPI,IPS,MIPS 4.翻译程序和汇编程序 5.计算机体系结构和计算机组成的区别和联系 6.基准程序执行得越快说明机器的性能越好吗? 1.机器字长&#xff0c;存储字长与指令字长 不同的机器三者…...

【STM32踩坑】HAL固件库版本过高导致烧录后无法运行问题

问题引入 目前STM32CUBEMX已经更新到了6.11版本&#xff0c;对应的固件库也一直在更新&#xff1b; 以STM32F1库为例&#xff0c;目前最新的库对应版本为1.8.5 但是我们会发现&#xff0c;如果直接使用1.8.5版本的固件库生成HAL源码后&#xff0c;烧录是可以烧录&#xff0c;但…...

芯片丝印反查

芯片丝印反查网 - 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论坛的开发任务&#xff0c;对php感兴趣的我开始迷恋上discuz这个产品了&#xff0c; 像戴志康这样的创新人才&#xff0c;是我们这代人的骄傲和学习的榜样 应该是了解一下&#xff0c;啥事discuzX2.5&#xff0c;百度看一下 discuz x2.5_百度百科 看完百度词条…...

【Python】 探索Django框架的高并发处理能力

基本原理 Django是一个高级的Python Web框架&#xff0c;它鼓励快速开发和干净、实用的设计。Django遵循MVC&#xff08;模型-视图-控制器&#xff09;设计模式&#xff0c;提供了一个全栈式的解决方案&#xff0c;使得开发者能够快速构建功能丰富的Web应用。Django的高并发处…...

C-数据结构-平横二叉树

平衡二叉树&#xff08;Balanced Binary Tree&#xff09;是一种二叉树&#xff0c;其中任意节点的两棵子树的高度差不超过 1。也可以说是一棵空树或者左右子树高度差不超过 1 的二叉树。 特点和性质 高度平衡&#xff1a;平衡二叉树是一种高度平衡的二叉树&#xff0c;任意节…...

算法训练营day41

动态规划理论基础&#xff08;主要就是确定动态规划的几个步骤&#xff09; 题目1&#xff1a;509. 斐波那契数 - 力扣&#xff08;LeetCode&#xff09; 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)

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

基于springboot+vue的班级综合测评管理系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…...

蓝海项目揭秘:跨境选品师的崛起与挑战

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

酷黑简洁大气体育直播自适应模板赛事直播门户网站源码

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

2024年电工杯高校数学建模竞赛(B题) 建模解析| 大学生平衡膳食食谱的优化设计

问题重述及方法概述 问题1&#xff1a;膳食食谱的营养分析评价及调整 数学方法&#xff1a;线性规划模型、营养素评价模型、比较分析 可视化数据图&#xff1a;营养素含量表、营养素摄入量对比图、营养素缺乏情况图 问题2&#xff1a;基于附件3的日平衡膳食食谱的优化设计 数…...

学习编程对英语要求高吗?

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

使用 Django 和 RabbitMQ 构建高效的消息队列系统

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

Pycharm常见问题1

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

开发一个comfyui的自定义节点

文章目录 目标功能开发环境comfyui自定义节点的实现原理仓库地址完整代码目标功能 开发一个comfyui的自定义节点,该节点的功能是:可以对comfyui工作流中最终输出的图像添加一些自定义文案,且可以指定文案在图像上的位置、文案的字体样式、字体大小、字体颜色等。最终效果如…...

Prime算法构造最小生成树(加点法)

一、算法逻辑 想要轻松形象理解Prime的算法逻辑&#xff0c;视频肯定比图文好。 小编看过很多求相关的教学视频&#xff0c;这里选出一个我认为最好理解的这一款安利给大家。 因为他不仅讲解细致&#xff0c;而且还配合了动画演示&#xff0c;可以说把一个抽象的东西讲的非常…...

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)

前言&#xff1a; 双亲委派机制对于面试这块来说非常重要&#xff0c;在实际开发中也是经常遇见需要打破双亲委派的需求&#xff0c;今天我们一起来探索一下什么是双亲委派机制&#xff0c;在此之前我们先介绍一下类的加载器。 目录 ​编辑 前言&#xff1a; 类加载器 1. …...

实战设计模式之模板方法模式

概述 模板方法模式定义了一个操作中的算法骨架&#xff0c;并将某些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的前提下&#xff0c;重新定义算法中的某些步骤。简单来说&#xff0c;就是在一个方法中定义了要执行的步骤顺序或算法框架&#xff0c;但允许子类…...

Python的__call__ 方法

在 Python 中&#xff0c;__call__ 是一个特殊的魔术方法&#xff08;magic method&#xff09;&#xff0c;它允许一个类的实例像函数一样被调用。当你在一个对象后面加上 () 并执行时&#xff08;例如 obj()&#xff09;&#xff0c;Python 会自动调用该对象的 __call__ 方法…...