vue实现页面拖拽布局
Vue 实现页面拖拽布局的方法
使用 Vue.Draggable 库
Vue.Draggable 是基于 Sortable.js 的 Vue 组件,适合实现列表或网格的拖拽排序。安装方式如下:
npm install vuedraggable
基本用法示例:

<template>
<draggable v-model="items" @end="onDragEnd">
<div v-for="item in items" :key="item.id">{{ item.name }}</div>
</draggable>
</template>
<script>
import draggable from 'vuedraggable';
export default {
components: { draggable },
data() {
return {
items: [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' }
]
};
},
methods: {
onDragEnd() {
console.log('拖拽完成后的顺序:', this.items);
}
}
};
</script>
使用原生 HTML5 Drag and Drop API
对于更基础的拖拽需求,可直接使用 HTML5 API:
<template>
<div
@dragover.prevent
@drop="handleDrop"
@dragstart="handleDragStart"
>
<div
v-for="item in items"
:key="item.id"
draggable="true"
@dragstart="handleDragStart(item)"
>
{{ item.name }}
</div>
</div>
</template>
<script>
export default {
data() {
return {
items: [...],
draggedItem: null
};
},
methods: {
handleDragStart(item) {
this.draggedItem = item;
},
handleDrop(e) {
const dropIndex = /* 计算放置位置 */;
this.items.splice(dropIndex, 0, this.draggedItem);
}
}
};
</script>
使用 Grid Layout 库
对于复杂网格布局,可使用 vue-grid-layout:

npm install vue-grid-layout
示例代码:
<template>
<grid-layout
:layout.sync="layout"
:col-num="12"
:row-height="30"
>
<grid-item
v-for="item in layout"
:x="item.x"
:y="item.y"
:w="item.w"
:h="item.h"
:i="item.i"
:key="item.i"
>
{{ item.content }}
</grid-item>
</grid-layout>
</template>
<script>
import { GridLayout, GridItem } from 'vue-grid-layout';
export default {
components: { GridLayout, GridItem },
data() {
return {
layout: [
{ x:0, y:0, w:2, h:2, i:'1', content: 'A' },
{ x:2, y:0, w:2, h:4, i:'2', content: 'B' }
]
};
}
};
</script>
自定义拖拽实现
对于特殊需求,可结合鼠标事件实现:
<template>
<div class="container" ref="container">
<div
v-for="item in items"
:key="item.id"
class="draggable-item"
:style="{ left: item.x + 'px', top: item.y + 'px' }"
@mousedown="startDrag(item, $event)"
>
{{ item.content }}
</div>
</div>
</template>
<script>
export default {
data() {
return {
items: [
{ id: 1, x: 0, y: 0, content: 'Box 1' }
],
dragging: null,
offsetX: 0,
offsetY: 0
};
},
mounted() {
document.addEventListener('mousemove', this.onDrag);
document.addEventListener('mouseup', this.stopDrag);
},
methods: {
startDrag(item, e) {
this.dragging = item;
this.offsetX = e.clientX - item.x;
this.offsetY = e.clientY - item.y;
},
onDrag(e) {
if (!this.dragging) return;
this.dragging.x = e.clientX - this.offsetX;
this.dragging.y = e.clientY - this.offsetY;
},
stopDrag() {
this.dragging = null;
}
}
};
</script>
<style>
.draggable-item {
position: absolute;
cursor: move;
}
</style>
选择建议
- 简单列表排序:Vue.Draggable 最合适,API 简单且功能完善。
- 自由布局拖拽:vue-grid-layout 提供响应式网格布局能力。
- 特殊交互需求:自定义实现可以完全控制拖拽逻辑,但开发成本较高。
- 基础学习:HTML5 API 适合理解底层原理,但需要自行处理更多边界情况。
所有方案都需要考虑移动端兼容性,部分库可能需要额外配置触摸事件支持。






