vue实现元素拖拽缩放
Vue 实现元素拖拽缩放
使用原生 HTML5 拖拽 API
在 Vue 中可以通过 @mousedown、@mousemove 和 @mouseup 事件监听实现拖拽功能。缩放功能可以通过监听元素的边缘或角落的拖动事件来实现。
<template>
<div
class="resizable-box"
:style="{
left: box.x + 'px',
top: box.y + 'px',
width: box.width + 'px',
height: box.height + 'px'
}"
@mousedown="startDrag"
>
<div class="resizer" @mousedown="startResize"></div>
</div>
</template>
<script>
export default {
data() {
return {
box: {
x: 100,
y: 100,
width: 200,
height: 200
},
isDragging: false,
isResizing: false,
startX: 0,
startY: 0
};
},
methods: {
startDrag(e) {
this.isDragging = true;
this.startX = e.clientX - this.box.x;
this.startY = e.clientY - this.box.y;
document.addEventListener('mousemove', this.drag);
document.addEventListener('mouseup', this.stopDrag);
},
drag(e) {
if (this.isDragging) {
this.box.x = e.clientX - this.startX;
this.box.y = e.clientY - this.startY;
}
},
stopDrag() {
this.isDragging = false;
document.removeEventListener('mousemove', this.drag);
document.removeEventListener('mouseup', this.stopDrag);
},
startResize(e) {
this.isResizing = true;
this.startX = e.clientX;
this.startY = e.clientY;
document.addEventListener('mousemove', this.resize);
document.addEventListener('mouseup', this.stopResize);
},
resize(e) {
if (this.isResizing) {
this.box.width = e.clientX - this.box.x;
this.box.height = e.clientY - this.box.y;
}
},
stopResize() {
this.isResizing = false;
document.removeEventListener('mousemove', this.resize);
document.removeEventListener('mouseup', this.stopResize);
}
}
};
</script>
<style>
.resizable-box {
position: absolute;
border: 1px solid #000;
background: #f0f0f0;
cursor: move;
}
.resizer {
width: 10px;
height: 10px;
background: #000;
position: absolute;
right: 0;
bottom: 0;
cursor: nwse-resize;
}
</style>
使用第三方库 vue-draggable-resizable
vue-draggable-resizable 是一个专门为 Vue 设计的拖拽和缩放组件,简化了实现过程。
安装:
npm install vue-draggable-resizable
使用:
<template>
<div>
<VueDraggableResizable
:w="200"
:h="200"
:x="100"
:y="100"
@dragging="onDrag"
@resizing="onResize"
>
<p>可拖拽缩放的元素</p>
</VueDraggableResizable>
</div>
</template>
<script>
import VueDraggableResizable from 'vue-draggable-resizable';
export default {
components: {
VueDraggableResizable
},
methods: {
onDrag(x, y) {
console.log('拖拽位置:', x, y);
},
onResize(x, y, width, height) {
console.log('缩放尺寸:', width, height);
}
}
};
</script>
使用 interact.js 实现高级交互
interact.js 是一个功能强大的拖拽、缩放和手势库,适合更复杂的交互需求。
安装:
npm install interactjs
使用:
<template>
<div
ref="box"
class="draggable-box"
:style="{
left: box.x + 'px',
top: box.y + 'px',
width: box.width + 'px',
height: box.height + 'px'
}"
>
可拖拽缩放的元素
</div>
</template>
<script>
import interact from 'interactjs';
export default {
data() {
return {
box: {
x: 100,
y: 100,
width: 200,
height: 200
}
};
},
mounted() {
interact(this.$refs.box)
.draggable({
onmove: (event) => {
this.box.x += event.dx;
this.box.y += event.dy;
}
})
.resizable({
edges: { left: true, right: true, bottom: true, top: true },
onmove: (event) => {
this.box.width = event.rect.width;
this.box.height = event.rect.height;
this.box.x += event.deltaRect.left;
this.box.y += event.deltaRect.top;
}
});
}
};
</script>
<style>
.draggable-box {
position: absolute;
border: 1px solid #000;
background: #f0f0f0;
cursor: move;
}
</style>
注意事项
- 性能优化:频繁的拖拽和缩放操作可能影响性能,建议使用
requestAnimationFrame或节流函数优化。 - 边界限制:可以通过条件判断限制元素的拖拽和缩放范围,防止超出容器。
- 触摸屏支持:如果需要支持触摸设备,确保事件监听包括
touchstart、touchmove和touchend。







