Element Plus предоставляет гибкие средства для реализации функционала
перетаскивания элементов (Drag and Drop) на основе
компонентов ElTable, ElTree и
ElDraggable (через интеграцию с vuedraggable).
Основной принцип заключается в управлении состоянием
данных, а не манипуляции DOM напрямую, что обеспечивает
реактивность и предсказуемое поведение интерфейса.
Компонент ElTable с возможностью перетаскивания строк
требует подключения внешней библиотеки, например
vuedraggable, для полноценной работы. Основные шаги:
import draggable from 'vuedraggable';
<template>
<el-table :data="tableData" style="width: 100%">
<draggable v-model="tableData" tag="tbody">
<el-table-column prop="name" label="Имя"></el-table-column>
<el-table-column prop="age" label="Возраст"></el-table-column>
</draggable>
</el-table>
</template>
<script>
export default {
data() {
return {
tableData: [
{ name: 'Иван', age: 28 },
{ name: 'Мария', age: 34 },
{ name: 'Пётр', age: 22 }
]
};
}
};
</script>
Ключевые моменты:
v-model связывает массив данных с компонентом
Draggable. Перетаскивание автоматически обновляет порядок элементов в
массиве.tag="tbody" сохраняет структуру таблицы, предотвращая
нарушение DOM.@start и @end
для отслеживания начала и конца перетаскивания.Компонент ElTree поддерживает встроенный drag
and drop через свойство draggable. Конфигурация
включает обработку событий для контроля над перемещением узлов.
<template>
<el-tree
:data="treeData"
:props="defaultProps"
draggable
@node-drag-start="handleDragStart"
@node-drag-end="handleDragEnd"
@node-drop="handleDrop"
>
</el-tree>
</template>
<script>
export default {
data() {
return {
treeData: [
{ label: 'Фрукты', children: [{ label: 'Яблоко' }, { label: 'Банан' }] },
{ label: 'Овощи', children: [{ label: 'Морковь' }, { label: 'Картофель' }] }
],
defaultProps: { children: 'children', label: 'label' }
};
},
methods: {
handleDragStart(node, event) {
console.log('Начало перетаскивания', node);
},
handleDragEnd(node, event) {
console.log('Конец перетаскивания', node);
},
handleDrop(draggingNode, dropNode, dropType, ev) {
console.log('Перетащено', draggingNode, 'на', dropNode, 'тип', dropType);
}
}
};
</script>
Ключевые моменты:
draggable активирует возможность перетаскивания
узлов.dropType может быть 'before',
'after' или 'inner', что позволяет гибко
управлять расположением элементов.node-drag-start и
node-drag-end позволяет реализовать кастомную логику
(например, проверку условий перемещения или визуальные подсказки).Для предотвращения перемещения определённых элементов используются методы проверки и условия:
handleDrop(draggingNode, dropNode, dropType, ev) {
if (dropNode.label === 'Запрещённая категория') {
this.$message.warning('Перемещение запрещено');
return false; // отменяет операцию
}
}
allowDrop для более тонкого контроля
на уровне ElTree.@end, возвращая
элементы в исходное состояние при нарушении условий.Element Plus автоматически применяет базовые стили для перетаскиваемых элементов, но их можно кастомизировать через CSS:
.draggable-chosen {
background-color: #f0f9ff;
border: 1px dashed #409eff;
}
.draggable-ghost {
opacity: 0.6;
}
draggable-chosen — активный элемент во время
перетаскивания.draggable-ghost — элемент-заглушка, который следует за
курсором.vuedraggable и Element
Plus.Чтобы изменения в порядке элементов сохранялись глобально, можно использовать Vuex или Pinia:
methods: {
onDragEnd() {
this.$store.commit('updateTableOrder', this.tableData);
}
}
v-model Draggable обеспечивает реактивное
обновление массива.@end или @node-drop, отправляя обновлённый
порядок элементов через API.Для мобильного drag and drop рекомендуется использовать
touch-совместимые версии vuedraggable или
подключать библиотеку SortableJS с опцией
forceFallback: true. Это обеспечивает плавное
перетаскивание на сенсорных экранах без конфликтов с стандартными
жестами.
ElTree поддерживает встроенные события и свойства для
гибкой настройки.ElTable требуется интеграция с
vuedraggable, что позволяет сохранять порядок строк через
реактивные массивы.