vue实现横向拖拽
实现横向拖拽的基本思路
使用 Vue 实现横向拖拽功能通常涉及监听鼠标事件(mousedown、mousemove、mouseup),计算拖拽距离,并动态更新元素位置。以下是核心实现方法:
基础实现步骤
模板部分
<template>
<div class="draggable-container" ref="container">
<div
class="draggable-item"
ref="draggable"
@mousedown="startDrag"
@mousemove="onDrag"
@mouseup="endDrag"
@mouseleave="endDrag"
:style="{ transform: `translateX(${offsetX}px)` }"
>
拖拽元素
</div>
</div>
</template>
脚本部分
<script>
export default {
data() {
return {
isDragging: false,
startX: 0,
offsetX: 0
};
},
methods: {
startDrag(e) {
this.isDragging = true;
this.startX = e.clientX - this.offsetX;
e.preventDefault();
},
onDrag(e) {
if (!this.isDragging) return;
this.offsetX = e.clientX - this.startX;
},
endDrag() {
this.isDragging = false;
}
}
};
</script>
样式部分

<style>
.draggable-container {
width: 100%;
overflow: hidden;
border: 1px solid #ccc;
}
.draggable-item {
width: 100px;
height: 50px;
background: #42b983;
cursor: grab;
user-select: none;
}
</style>
进阶优化:限制拖拽边界
为防止元素拖出容器,可添加边界检查逻辑:
onDrag(e) {
if (!this.isDragging) return;
const newOffset = e.clientX - this.startX;
const containerWidth = this.$refs.container.offsetWidth;
const itemWidth = this.$refs.draggable.offsetWidth;
// 限制右边界
if (newOffset > 0) {
this.offsetX = 0;
return;
}
// 限制左边界
if (newOffset < containerWidth - itemWidth) {
this.offsetX = containerWidth - itemWidth;
return;
}
this.offsetX = newOffset;
}
使用第三方库(如 Vue.Draggable)
对于复杂场景,推荐使用成熟库:

-
安装依赖:
npm install vuedraggable -
横向拖拽列表示例:
<template> <draggable v-model="items" direction="horizontal" @start="drag=true" @end="drag=false"> <div v-for="item in items" :key="item.id" class="item"> {{ item.name }} </div> </draggable> </template>
移动端适配
添加触摸事件支持:
<div
@touchstart="startDrag"
@touchmove="onDrag"
@touchend="endDrag"
></div>
methods: {
startDrag(e) {
const clientX = e.type.includes('touch') ? e.touches[0].clientX : e.clientX;
this.isDragging = true;
this.startX = clientX - this.offsetX;
},
onDrag(e) {
const clientX = e.type.includes('touch') ? e.touches[0].clientX : e.clientX;
// 其余逻辑相同
}
}
性能优化建议
- 使用
transform代替left属性实现位移,避免触发重排 - 对于大量可拖拽元素,采用虚拟滚动技术
- 使用
requestAnimationFrame节流拖拽事件onDrag(e) { if (!this.isDragging) return; window.requestAnimationFrame(() => { const clientX = e.type.includes('touch') ? e.touches[0].clientX : e.clientX; this.offsetX = clientX - this.startX; }); }






