vue实现拖动放大缩小
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>






