Drag and Drop (DnD) является мощным инструментом для реализации интерактивных интерфейсов, позволяя пользователю перетаскивать элементы и менять их порядок, перемещать между контейнерами или работать с визуальными компонентами. В экосистеме Vue.js существует несколько подходов к внедрению DnD, включая нативный HTML5 Drag and Drop API и специализированные библиотеки, оптимизированные для реактивной модели Vue.
HTML5 API предоставляет базовый набор событий:
dragstart, dragover, dragenter,
dragleave, drop и dragend. В
Vue.js события можно обрабатывать через директиву v-on.
Пример реализации простого перетаскивания элементов списка:
<template>
<ul>
<li v-for="(item, index) in items" :key="item.id"
draggable="true"
@dragstart="dragStart(index)"
@dragover.prevent
@drop="dr op ( index)">
{{ item.name }}
</li>
</ul>
</template>
<script>
export default {
data() {
return {
items: [
{ id: 1, name: 'Элемент 1' },
{ id: 2, name: 'Элемент 2' },
{ id: 3, name: 'Элемент 3' }
],
draggedIndex: null
}
},
methods: {
dragStart(index) {
this.draggedIndex = index;
},
dr op ( index) {
const draggedItem = this.items[this.draggedIndex];
this.items.splice(this.draggedIndex, 1);
this.items.splice(index, 0, draggedItem);
this.draggedIndex = null;
}
}
}
</script>
Ключевые моменты:
draggable="true" для элементов..prevent на dragover, чтобы
разрешить сброс.data компонента.Нативный API подходит для простых сценариев, но для сложных интерфейсов рекомендуется использовать библиотеки:
<template>
<draggable v-model="items" @end="onEnd">
<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: 'Элемент 1' },
{ id: 2, name: 'Элемент 2' },
{ id: 3, name: 'Элемент 3' }
]
}
},
methods: {
onEnd(event) {
console.log('Элемент перемещен', event);
}
}
}
</script>
Особенности Vue.Draggable:
@start, @end, @add,
@remove, @update позволяют гибко управлять
логикой приложения.<template>
<Draggable v-model="tasks">
<template #item="{element}">
<div>{{ element.name }}</div>
</template>
</Draggable>
</template>
<script>
import { ref } from 'vue';
import Draggable from 'vuedraggable';
export default {
components: { Draggable },
setup() {
const tasks = ref([
{ id: 1, name: 'Задача 1' },
{ id: 2, name: 'Задача 2' },
{ id: 3, name: 'Задача 3' }
]);
return { tasks };
}
}
</script>
Преимущества:
:key) при рендере списков,
чтобы избежать проблем с реактивностью.Реализация Drag and Drop в Vue.js позволяет создавать интуитивно понятные, визуально насыщенные интерфейсы без потери реактивности и управляемости данных.