Drag.vue 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. <template>
  2. <div
  3. class="drag-container "
  4. :class="className"
  5. >
  6. <slot />
  7. </div>
  8. </template>
  9. <script setup lang="ts">
  10. import {
  11. nextTick,
  12. ref
  13. } from 'vue'
  14. const props = withDefaults(defineProps<{
  15. domClassName: string,
  16. }>(), {
  17. domClassName: ''
  18. })
  19. const className = ref(`drag-${Math.random() * 10000}`)
  20. nextTick(() => {
  21. const dragDom = document.getElementsByClassName(className.value)[0] as HTMLElement
  22. if (!dragDom) return
  23. const targetDom = dragDom.getElementsByClassName(props.domClassName)[0] as HTMLElement
  24. let isDrag = false
  25. const mouseDown = (e: any) => {
  26. if (!targetDom.contains(e.target)) return
  27. isDrag = true
  28. const X = e.clientX - dragDom.offsetLeft
  29. const Y = e.clientY - dragDom.offsetTop
  30. const move = (event: MouseEvent) => {
  31. event.preventDefault()
  32. if (isDrag) {
  33. dragDom.style.left = `${event.clientX - X}px`
  34. dragDom.style.top = `${event.clientY - Y}px`
  35. dragDom.style.right = 'auto'
  36. }
  37. }
  38. document.addEventListener('mousemove', move, false)
  39. document.addEventListener('mouseup', () => {
  40. isDrag = false
  41. document.removeEventListener('mousemove', move)
  42. })
  43. }
  44. dragDom.addEventListener('mousedown', mouseDown)
  45. })
  46. </script>
  47. <style scoped>
  48. .drag-container {
  49. position: absolute !important;
  50. z-index: 100;
  51. }
  52. </style>