1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/**
 * v-dialog-drag:让 Element UI 2.x 的 el-dialog 能用标题栏拖动。
 * Element UI 2.x 的 el-dialog 没有 draggable 属性(那是 Element Plus 的功能),
 * 所以这里用指令实现:只改 .el-dialog 的 transform,不改布局;
 * 弹窗关闭(wrapper 被置为 display:none)时自动复位,下次打开仍在原位。
 * 用法:<el-dialog v-dialog-drag custom-class="xxx">
 */
export default {
  inserted(el) {
    const dialog = el.querySelector('.el-dialog')
    const header = el.querySelector('.el-dialog__header')
    if (!dialog || !header) return
    let startX = 0
    let startY = 0
    let baseX = 0
    let baseY = 0
    let curX = 0
    let curY = 0
    let dragging = false
 
    const reset = () => {
      curX = 0
      curY = 0
      dialog.style.transform = ''
    }
    const onMove = (e) => {
      if (!dragging) return
      curX = baseX + (e.clientX - startX)
      curY = baseY + (e.clientY - startY)
      dialog.style.transform = 'translate(' + curX + 'px, ' + curY + 'px)'
      if (e.preventDefault) e.preventDefault()
    }
    const onUp = () => {
      if (!dragging) return
      dragging = false
      document.removeEventListener('mousemove', onMove)
      document.removeEventListener('mouseup', onUp)
    }
    const onDown = (e) => {
      if (e.button !== 0) return
      const t = e.target
      if (t && t.closest && t.closest('.el-dialog__headerbtn')) return
      dragging = true
      startX = e.clientX
      startY = e.clientY
      baseX = curX
      baseY = curY
      document.addEventListener('mousemove', onMove)
      document.addEventListener('mouseup', onUp)
      if (e.preventDefault) e.preventDefault()
    }
 
    header.addEventListener('mousedown', onDown)
    if (typeof MutationObserver !== 'undefined') {
      const mo = new MutationObserver(() => {
        if (el.style.display === 'none') reset()
      })
      mo.observe(el, { attributes: true, attributeFilter: ['style'] })
    }
  }
}