当前位置:首页 > 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
    })
  }
})

模板使用:

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

vue实现拖动放大缩小

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

相关文章

vue穿梭框组件实现

vue穿梭框组件实现

实现基础穿梭框组件 在Vue中实现穿梭框组件,可以使用<el-transfer>(Element UI)或手动实现。以下是手动实现的核心逻辑: <template> &…

vue   实现单选

vue 实现单选

Vue 实现单选功能 在 Vue 中实现单选功能可以通过多种方式,以下是几种常见的方法: 使用原生 <input type="radio"> 绑定 v-model 通过 v-model…

vue实现功能

vue实现功能

Vue 功能实现方法 Vue.js 是一个渐进式 JavaScript 框架,用于构建用户界面。以下是实现常见功能的几种方法: 数据绑定与响应式更新 在 Vue 中,数据绑定通过 v-model…

vue SSG实现

vue SSG实现

Vue SSG 实现方法 Vue 的静态站点生成(SSG)可以通过多种工具和框架实现,以下是几种常见的方法: 使用 VuePress VuePress 是一个基于 Vue 的静态站点生成器,适合文…

vue 实现fadeout

vue 实现fadeout

Vue 实现淡出效果 在 Vue 中实现淡出(fade-out)效果可以通过 CSS 过渡或动画结合 Vue 的动态渲染功能完成。以下是几种常见方法: 使用 Vue 过渡(Transition)组…

vue实现双向

vue实现双向

Vue 实现双向绑定的方法 Vue 的双向绑定主要通过 v-model 指令实现,它结合了数据绑定和事件监听,适用于表单元素(如 input、select、textarea 等)。以下是几种常见的实现…