Vue2+ElementUI 弹窗全局拖拽 支持放大缩小

拖拽组件

dialogDrag.vue

复制代码
<template>
  <div></div>
</template>
<script>
  export default {
    name: 'dialogDrag',
    data() {
      return {
        originalWidth: null,
        originalHeight: null
      }
    },
    created() {
      this.$nextTick(()=>{
        this.dialogDrag()
      })
    },
    mounted() {
    },
    methods: {
      dialogDrag(){
        //获取弹窗DOM
        let dragDom = this.$el.getElementsByClassName('el-dialog')[0]
        // this.originalWidth = dragDom.style.width
        // this.originalHeight = dragDom.style.height
        //弹窗标题顶部DOM
        let dialogHeaderDom = this.$el.getElementsByClassName('el-dialog__header')[0]
        //设置拖动样式
        dialogHeaderDom.style.cursor = 'move'

        let mousedown = false

        const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null)
        //鼠标按下弹窗顶部
        dialogHeaderDom.onmousedown = (e) => {
          if(e.stopPropagation) e.stopPropagation();
          if(e.preventDefault) e.preventDefault();
          if (e.detail === 2) {
            if (this.originalWidth || this.originalHeight) {
              // 还原弹窗的宽度和高度
              dragDom.style.width = this.originalWidth
              dragDom.style.height = this.originalHeight
              this.originalWidth = null
              this.originalHeight = null
            } else {
              // 保存当前弹窗的宽度和高度
              this.originalWidth = dragDom.style.width
              this.originalHeight = dragDom.style.height
              // 设置弹窗宽度和高度为窗口的宽度和高度
              dragDom.style.width = '100vw'
              dragDom.style.height = window.innerHeight + 'px'
              dragDom.style.overflow= 'auto'
            }
            mousedown = false
            document.onmousemove = null
            document.onmouseup = null
          }
          mousedown = true // 鼠标距离弹框的距离
          //获取鼠标拖拽起始X位置
          const startLeft = e.clientX - dialogHeaderDom.offsetLeft
          //获取鼠标拖拽起始Y位置
          const startTop = e.clientY - dialogHeaderDom.offsetTop // 现在弹框的left,top

          let styL, styT

          if (sty.left.includes('%')) {
            styL = +document.body.clientWidth * (+sty.left.replace('%', '') / 100)
            styT = +document.body.clientHeight * (+sty.top.replace('%', '') / 100)

          } else {
            styL = +sty.left.replace('px', '')
            styT = +sty.top.replace('px', '')
          }

          document.onmousemove = function(e) {
            if (!mousedown) {
              return false
            } // 鼠标移动的距离 + 弹框的left/top
            let l = e.clientX - startLeft + styL
            let t = e.clientY - startTop + styT

            const offsetParent = dragDom.offsetParent || document.body

            const maxL = offsetParent.clientWidth - dragDom.clientWidth
            //设置拖拽到底部最大高度4分之1
            const maxT = offsetParent.clientHeight - dragDom.clientHeight + (sty.height.toString().split('p') && Number(sty.height.toString().split('p')[0])/1.5)
            if (maxL < l) {
              l = maxL
            } else if (l < 0 && l * -1 > startLeft) {
              // 向左偏移的距离 l = -startLeft;
            }
            if (t < 0) {
              t = 0
            } else if (maxT < t) {
              t = maxT
            }
            dragDom.style.left = `${l}px`
            dragDom.style.top = `${t}px`
          }
          // document.onmouseup = function(e) {
          //   mousedown = false
          //   document.onmousemove = null
          //   document.onmouseup = null
          // }
          document.body.addEventListener('mouseup', () => {
            // mouseup 需要执行的代码块
            mousedown = false
            document.onmousemove = null
            document.onmouseup = null
          })
        }
      }
    }
  }
</script>

<style scoped>

</style>

index.js

复制代码
import dialogDragMixin from './dialogDrag'

export function installElement(Vue, Element) {

  Element.Dialog.mixins.push(dialogDragMixin);

}

main.js

复制代码
import { installElement } from '@/config/element';
installElement(Vue, Element);

创建目录

相关推荐
whatever who cares15 小时前
Vue3中vue文件和composables的分工
前端·javascript·vue.js
十正15 小时前
Claude code源码精读之蜂群模式
javascript·人工智能·agent·claude code
薛先生_09915 小时前
vue-编程式跳转-基本跳转
前端·javascript·vue.js
AI_零食15 小时前
健身室器材管理系统鸿蒙PC Electron框架编写深度解析
前端·javascript·学习·华为·electron·前端框架·鸿蒙
如烟花的信页16 小时前
易盾点选逆向分析
javascript·爬虫·python·js逆向
ZC跨境爬虫16 小时前
跟着 MDN 学 JavaScript day_2:JavaScript 初体验
开发语言·前端·javascript·学习·ecmascript
小妖66616 小时前
Hydration completed but contains mismatches
javascript·vue·vuepress
睡觉的时候不困617 小时前
TypedSql:在 C# 类型系统上实现一个 SQL 查询引擎
javascript
AI英德西牛仔17 小时前
Claude 导出 pdf 颜色不一样怎么办,选用 AI 导出鸭优化格式转换,多维度落地修正 PDF 色彩失真问题
javascript·人工智能·ai·chatgpt·pdf·deepseek·ai导出鸭
右耳朵猫AI17 小时前
JS/TS周刊2026W21 | Deno2.8RC、Angular22RC、TypeORM1.0
开发语言·javascript·ecmascript