您好,欢迎访问代理记账网站
移动应用 微信公众号 联系我们

咨询热线 -

电话 15988168888

联系客服
  • 价格透明
  • 信息保密
  • 进度掌控
  • 售后无忧

Vue中使用element-ui的el-dialog对话框,实现拖拽效果(整理)

1、准备:在准备一个vue组件(点击按钮弹出对话框):在vue组件中添加**v-dialogDrag**属性
 	//自定义指令:  v-dialogDrag
	//点击遮罩层关闭对话框: close-on-click-modal
<el-dialog v-dialogDrag :close-on-click-modal="false" title="我是标题" :visible.sync="mipLightbox"></el-dialog>

2、自定义指令:在src/assrts文件夹下创建dialogDrag.js文件(assrts-您自己定义的存放组件的文件夹下。。assrts-我自己存的文件夹下-如下图一)

3、引用:在main.js文件中全局引用-下图2-引入

4、以上工作完成之后可直接查看-拖拽效果


//一、这个可以拖拽出body外面-如果拖拽区域已被拖拽出去后-就拖拽不出来了-dialogDrag.js(可根据需求选择是用一、的js,还是二、的js。任选其一)
//自定义指令:实现element-ui对话框dialog拖拽功能
import Vue from 'vue'
// v-dialogDrag: 弹窗拖拽
Vue.directive('dialogDrag', {
  bind(el, binding, vnode, oldVnode) {
    const dialogHeaderEl = el.querySelector('.el-dialog__header')
    const dragDom = el.querySelector('.el-dialog')
    dialogHeaderEl.style.cursor = 'move'
 
    // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
    const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null)
 
    dialogHeaderEl.onmousedown = (e) => {
      // 鼠标按下,获得鼠标在盒子内的坐标(鼠标在页面的坐标 减去 对话框的坐标),计算当前元素距离可视区的距离
      const disX = e.clientX - dialogHeaderEl.offsetLeft
      const disY = e.clientY - dialogHeaderEl.offsetTop
 
      // 获取到的值带px 正则匹配替换
      let styL, styT
 
      // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
      if (sty.left.includes('%')) {
        styL = +document.body.clientWidth * (+sty.left.replace(/\%/g, '') / 100)
        styT = +document.body.clientHeight * (+sty.top.replace(/\%/g, '') / 100)
      } else {
        styL = +sty.left.replace(/\px/g, '')
        styT = +sty.top.replace(/\px/g, '')
      }
 
      document.onmousemove = function(e) {
        // 鼠标移动,用鼠标在页面的坐标 减去 鼠标在盒子里的坐标,获得模态框的left和top值
        // 通过事件委托,计算移动的距离
        const l = e.clientX - disX
        const t = e.clientY - disY
 
        // 移动当前元素
        dragDom.style.left = `${l + styL}px`
        dragDom.style.top = `${t + styT}px`
 
        // 将此时的位置传出去
        // binding.value({x:e.pageX,y:e.pageY})
      }
 
      document.onmouseup = function(e) {
        //  鼠标弹起,移除鼠标移动事件
        document.onmousemove = null
        document.onmouseup = null
      }
    }
  }
})

//二、这个在可视区域内拖拽-dialogDrag.js(可根据需求选择是用一、的js,还是二、的js。任选其一)
import Vue from 'vue';
// v-dialogDrag: 弹窗拖拽属性
Vue.directive('dialogDrag', {
    bind(el, binding, vnode, oldVnode) {
        const dialogHeaderEl = el.querySelector('.el-dialog__header');
        const dragDom = el.querySelector('.el-dialog');
 
        dialogHeaderEl.style.cssText += ';cursor:move;'
        dragDom.style.cssText += ';top:0px;'
 
        // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
        const sty = (() => {
            if (window.document.currentStyle) {
                return (dom, attr) => dom.currentStyle[attr];
            } else {
                return (dom, attr) => getComputedStyle(dom, false)[attr];
            }
        })()
 
        dialogHeaderEl.onmousedown = (e) => {
            // 鼠标按下,计算当前元素距离可视区的距离
            const disX = e.clientX - dialogHeaderEl.offsetLeft;
            const disY = e.clientY - dialogHeaderEl.offsetTop;
 
            const screenWidth = document.body.clientWidth; // body当前宽度
            const screenHeight = document.documentElement.clientHeight; // 可见区域高度(应为body高度,可某些环境下无法获取)
 
            const dragDomWidth = dragDom.offsetWidth; // 对话框宽度
            const dragDomheight = dragDom.offsetHeight; // 对话框高度
 
            const minDragDomLeft = dragDom.offsetLeft;
            const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth;
 
            const minDragDomTop = dragDom.offsetTop;
            const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomheight;
 
            // 获取到的值带px 正则匹配替换
            let styL = sty(dragDom, 'left');
            let styT = sty(dragDom, 'top');
 
            // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
            if (styL.includes('%')) {
                styL = +document.body.clientWidth * (+styL.replace(/\%/g, '') / 100);
                styT = +document.body.clientHeight * (+styT.replace(/\%/g, '') / 100);
            } else {
                styL = +styL.replace(/\px/g, '');
                styT = +styT.replace(/\px/g, '');
            };
 
            document.onmousemove = function (e) {
                // 通过事件委托,计算移动的距离
                let left = e.clientX - disX;
                let top = e.clientY - disY;
 
                // 边界处理
                if (-(left) > minDragDomLeft) {
                    left = -(minDragDomLeft);
                } else if (left > maxDragDomLeft) {
                    left = maxDragDomLeft;
                }
 
                if (-(top) > minDragDomTop) {
                    top = -(minDragDomTop);
                } else if (top > maxDragDomTop) {
                    top = maxDragDomTop;
                }
 
                // 移动当前元素 
                dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;`;
            };
 
            document.onmouseup = function (e) {
                document.onmousemove = null;
                document.onmouseup = null;
            };
        }
    }
})

图一:dialogDrag.js文件存放位置在这里插入图片描述

图二:dialogDrag.js文件-在main.js文件中全局引用
在这里插入图片描述


分享:

低价透明

统一报价,无隐形消费

金牌服务

一对一专属顾问7*24小时金牌服务

信息保密

个人信息安全有保障

售后无忧

服务出问题客服经理全程跟进