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

<template>
<draggable v-model="list" @end="onDragEnd">
<div v-for="item in list" :key="item.id">{{ item.name }}</div>
</draggable>
</template>
<script>
import draggable from 'vuedraggable';
export default {
components: { draggable },
data() {
return {
list: [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' }
]
}
},
methods: {
onDragEnd() {
console.log('拖拽完成');
}
}
}
</script>
使用原生 HTML5 Drag and Drop API
对于更基础的拖拽需求,可直接使用 HTML5 API 实现:

<template>
<div
v-for="item in items"
:key="item.id"
draggable="true"
@dragstart="handleDragStart($event, item)"
@dragover.prevent
@drop="handleDrop($event, item)"
>
{{ item.text }}
</div>
</template>
<script>
export default {
data() {
return {
items: [
{ id: 1, text: 'Element A' },
{ id: 2, text: 'Element B' }
],
draggedItem: null
}
},
methods: {
handleDragStart(e, item) {
this.draggedItem = item;
e.dataTransfer.effectAllowed = 'move';
},
handleDrop(e, targetItem) {
const index = this.items.indexOf(this.draggedItem);
this.items.splice(index, 1);
const targetIndex = this.items.indexOf(targetItem);
this.items.splice(targetIndex, 0, this.draggedItem);
}
}
}
</script>
使用 Grid 布局拖拽
结合 CSS Grid 实现更复杂的拖拽布局:
<template>
<div class="grid-container" ref="grid">
<div
v-for="item in items"
:key="item.id"
class="grid-item"
draggable="true"
@dragstart="dragStart"
@dragover.prevent
@dragenter.prevent
@drop="drop"
:style="{ gridArea: item.area }"
>
{{ item.content }}
</div>
</div>
</template>
<script>
export default {
data() {
return {
items: [
{ id: 1, content: 'Box 1', area: '1 / 1 / 2 / 2' },
{ id: 2, content: 'Box 2', area: '1 / 2 / 2 / 3' }
],
draggedItem: null
}
},
methods: {
dragStart(e) {
this.draggedItem = e.target;
e.dataTransfer.setData('text/plain', e.target.id);
},
drop(e) {
const target = e.target;
if (target !== this.draggedItem) {
const tempArea = target.style.gridArea;
target.style.gridArea = this.draggedItem.style.gridArea;
this.draggedItem.style.gridArea = tempArea;
}
}
}
}
</script>
<style>
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
}
.grid-item {
border: 1px solid #ccc;
padding: 20px;
}
</style>
使用第三方 UI 库
Element UI、Ant Design Vue 等库提供现成的拖拽组件:
<template>
<el-row :gutter="10">
<el-col
v-for="(item, index) in list"
:key="index"
:span="6"
v-dragging="{ item: item, list: list, group: 'item' }"
>
{{ item }}
</el-col>
</el-row>
</template>
<script>
export default {
data() {
return {
list: ['Item 1', 'Item 2', 'Item 3']
}
},
mounted() {
this.$dragging.$on('dragged', ({ value }) => {
console.log(value.item);
});
}
}
</script>
注意事项
- 移动端适配需额外处理 touch 事件
- 复杂场景建议使用专业库如 interact.js
- 拖拽性能优化可考虑虚拟滚动技术
- 持久化布局状态应配合 localStorage 或后端存储
以上方法可根据具体需求选择实现方案,Vue.Draggable 适合大多数简单场景,HTML5 API 提供更底层控制,Grid 布局适合响应式设计,UI 库方案则提供开箱即用体验。






