当前位置:首页 > VUE

vue实现拖动放大缩小

2026-02-22 22:09:55VUE

Vue实现拖动放大缩小的方法

使用vue-draggable-resizable库

安装vue-draggable-resizable库:

npm install vue-draggable-resizable --save

注册组件:

import VueDraggableResizable from 'vue-draggable-resizable'

export default {
  components: {
    VueDraggableResizable
  }
}

模板中使用:

<vue-draggable-resizable 
  :w="200" 
  :h="200"
  :x="0"
  :y="0"
  @dragging="onDrag"
  @resizing="onResize">
  <p>可拖动和调整大小的元素</p>
</vue-draggable-resizable>

事件处理:

methods: {
  onDrag(x, y) {
    console.log(x, y)
  },
  onResize(x, y, width, height) {
    console.log(x, y, width, height)
  }
}

使用原生HTML5拖放API

模板结构:

<div 
  class="resizable-box"
  @mousedown="startDrag"
  @mousemove="onDrag"
  @mouseup="stopDrag">
  <div class="resizer" @mousedown="startResize"></div>
</div>

样式设置:

.resizable-box {
  position: absolute;
  border: 1px solid #000;
  cursor: move;
}

.resizer {
  width: 10px;
  height: 10px;
  background: #000;
  position: absolute;
  right: 0;
  bottom: 0;
  cursor: nwse-resize;
}

逻辑实现:

data() {
  return {
    isDragging: false,
    isResizing: false,
    startX: 0,
    startY: 0,
    box: {
      x: 0,
      y: 0,
      width: 200,
      height: 200
    }
  }
},
methods: {
  startDrag(e) {
    this.isDragging = true
    this.startX = e.clientX - this.box.x
    this.startY = e.clientY - this.box.y
  },
  onDrag(e) {
    if (!this.isDragging) return
    this.box.x = e.clientX - this.startX
    this.box.y = e.clientY - this.startY
  },
  stopDrag() {
    this.isDragging = false
  },
  startResize(e) {
    e.stopPropagation()
    this.isResizing = true
    this.startX = e.clientX
    this.startY = e.clientY
  }
}

使用第三方库interact.js

安装interact.js:

npm install interactjs

组件实现:

import interact from 'interactjs'

export default {
  mounted() {
    interact('.draggable')
      .draggable({
        onmove: this.dragMoveListener
      })
      .resizable({
        edges: { left: true, right: true, bottom: true, top: true },
        listeners: {
          move: this.resizeListener
        }
      })
  },
  methods: {
    dragMoveListener(event) {
      const target = event.target
      const x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx
      const y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy

      target.style.transform = `translate(${x}px, ${y}px)`
      target.setAttribute('data-x', x)
      target.setAttribute('data-y', y)
    },
    resizeListener(event) {
      const target = event.target
      let x = (parseFloat(target.getAttribute('data-x')) || 0)
      let y = (parseFloat(target.getAttribute('data-y')) || 0)

      target.style.width = `${event.rect.width}px`
      target.style.height = `${event.rect.height}px`

      x += event.deltaRect.left
      y += event.deltaRect.top

      target.style.transform = `translate(${x}px, ${y}px)`
      target.setAttribute('data-x', x)
      target.setAttribute('data-y', y)
    }
  }
}

使用Vue指令实现

自定义指令:

Vue.directive('drag-resize', {
  bind(el, binding) {
    let isDragging = false
    let isResizing = false
    let startX, startY

    el.style.position = 'absolute'
    el.style.cursor = 'move'

    const resizer = document.createElement('div')
    resizer.style.width = '10px'
    resizer.style.height = '10px'
    resizer.style.background = '#000'
    resizer.style.position = 'absolute'
    resizer.style.right = '0'
    resizer.style.bottom = '0'
    resizer.style.cursor = 'nwse-resize'
    el.appendChild(resizer)

    el.addEventListener('mousedown', (e) => {
      if (e.target === resizer) {
        isResizing = true
      } else {
        isDragging = true
      }
      startX = e.clientX - el.offsetLeft
      startY = e.clientY - el.offsetTop
    })

    document.addEventListener('mousemove', (e) => {
      if (isDragging) {
        el.style.left = `${e.clientX - startX}px`
        el.style.top = `${e.clientY - startY}px`
      }
      if (isResizing) {
        el.style.width = `${e.clientX - el.offsetLeft}px`
        el.style.height = `${e.clientY - el.offsetTop}px`
      }
    })

    document.addEventListener('mouseup', () => {
      isDragging = false
      isResizing = false
    })
  }
})

模板使用:

vue实现拖动放大缩小

<div v-drag-resize style="width: 200px; height: 200px; background: #eee;">
  可拖动和调整大小的元素
</div>

标签: 拖动vue
分享给朋友:

相关文章

vue 实现视频

vue 实现视频

Vue 实现视频播放功能 使用 Vue 实现视频播放功能可以通过 HTML5 的 <video> 标签或第三方库(如 video.js)来实现。以下是两种常见的方法: 使用 HTML5…

vue实现gps

vue实现gps

Vue 中实现 GPS 定位功能 在 Vue 中实现 GPS 定位功能通常依赖于浏览器的 Geolocation API 或第三方地图服务(如高德、百度地图等)。以下是两种常见的实现方式: 使用浏览…

vue 实现长按

vue 实现长按

实现长按功能的基本思路 在Vue中实现长按功能,通常需要监听元素的mousedown或touchstart事件,启动一个计时器。当用户按住元素超过设定的时间阈值时,触发长按回调函数。如果在时间阈值内触…

vue实现tabs

vue实现tabs

Vue实现Tabs组件的方法 使用动态组件和v-for指令 在Vue中创建Tabs组件可以通过动态组件和v-for指令实现。定义一个包含tab标题和内容的数组,使用v-for渲染tab标题,并通过点击…

vue实现复制

vue实现复制

Vue 实现复制功能 在 Vue 中实现复制功能可以通过多种方式完成,以下是几种常见的方法: 方法一:使用 Clipboard API Clipboard API 是现代浏览器提供的一种原生 AP…

vue实现计数

vue实现计数

Vue 实现计数功能 在 Vue 中实现计数功能可以通过多种方式完成,以下是几种常见的方法: 使用 Vue 数据绑定和事件监听 通过 Vue 的数据绑定和事件监听,可以轻松实现计数功能。以下是一个简…