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);

创建目录

相关推荐
掘金安东尼39 分钟前
让 JavaScript 更容易「善后」的新能力
前端·javascript·面试
掘金安东尼40 分钟前
用 HTMX 为 React Data Grid 加速实时更新
前端·javascript·面试
灵感__idea3 小时前
Hello 算法:众里寻她千“百度”
前端·javascript·算法
袋鼠云数栈UED团队4 小时前
基于 Lexical 实现变量输入编辑器
前端·javascript·架构
亦妤4 小时前
JS执行机制、作用域及作用域链
javascript
SuperEugene6 小时前
表单最佳实践:从 v-model 到自定义表单组件(含校验)
前端·javascript·vue.js
不会敲代码16 小时前
React性能优化:深入理解useMemo和useCallback
前端·javascript·react.js
YukiMori238 小时前
一个有趣的原型继承实验:为什么“男人也会生孩子”?从对象赋值到构造函数继承的完整推演
前端·javascript
摸鱼的春哥9 小时前
惊!黑客靠AI把墨西哥政府打穿了,海量数据被黑
前端·javascript·后端
小兵张健9 小时前
Playwright MCP 截图标注方案调研(推荐方案1)
前端·javascript·github