Привет, Хабр! Сегодня я хочу представить вам свой новый проект — Vue DnD Kit, легковесную и производительную библиотеку для создания интерфейсов с перетаскиванием (drag and drop) для Vue 3.
Важно: Эта публикация — краткая новость о выходе библиотеки. Для полноценных примеров и подробной документации рекомендую перейти на официальный сайт документации.
Почему я создал еще одну библиотеку для drag and drop?
В экосистеме Vue уже существует несколько решений для реализации drag and drop, но большинство из них либо устарели, либо имеют ограничения в производительности и гибкости. Вдохновившись популярной библиотекой dnd-kit для React, я решил создать аналогичное решение для Vue 3, которое было бы:
-
Легковесным — минимальное влияние на размер бандла
-
Производительным — оптимизировано для работы даже с большими списками
-
Гибким — позволяет реализовать практически любой сценарий перетаскивания
-
Доступным — полная поддержка клавиатурной навигации и скринридеров
Ключевые особенности Vue DnD Kit
1. Простой API на основе композабельных функций
Библиотека предоставляет интуитивно понятный API, основанный на композабельных функциях Vue 3:
import { useDraggable, useDroppable } from '@vue-dnd-kit/core'; // Для перетаскиваемого элемента const { elementRef, handleDragStart, isDragging } = useDraggable(); // Для области, куда можно перетащить const { elementRef: dropRef, isOvered } = useDroppable({ events: { onDrop: () => console.log('Элемент брошен!') } });
2. Полная поддержка клавиатурной навигации
Одна из уникальных особенностей библиотеки — полная поддержка управления с клавиатуры:
-
W A S D для перемещения элементов
-
Space/Enter для выбора и сброса
-
Escape для отмены операции перетаскивания
-
Tab для навигации между элементами
Это делает ваши интерфейсы доступными для всех пользователей, включая тех, кто не может использовать мышь.
3. Высокая производительность
Vue DnD Kit оптимизирован для работы даже с большими списками и сложными интерфейсами:
-
Минимальные перерисовки компонентов
-
Эффективные операции с DOM
-
Предотвращение утечек памяти
4. Полная кастомизация
-
Возможность изменять вид контейнера
-
Возможность изменять вид отображения драгаемого элемента / (драгаемых элементов)
-
Поддержка групп
-
Возможность полностью написать свой сенсор детекта элемента где под капотом уже работает автоматическое определение приоритета элемента и доступности его (возможно зона имеет группы в которые элемент / элементы не могут попасть)
-
Поддержка throttle с кастомным сенсором
-
Поддержка анимаций как CSS так и JS библиотек для анимаций GSAP, Anime.js и тд тп.
-
Возможность полностью написать свою логику дропа
Примеры использования
<template> <div class="container"> <Draggable v-if="!elementInDropZone"> Перетащи меня! </Draggable> <Droppable @drop="handleDrop"> <Draggable v-if="elementInDropZone" @end="handleEnd"> Я в зоне сброса! </Draggable> </Droppable> </div> </template> <script setup> import { ref } from 'vue'; import Draggable from './components/Draggable.vue'; import Droppable from './components/Droppable.vue'; const elementInDropZone = ref(false); const handleDrop = () => elementInDropZone.value = true; const handleEnd = () => elementInDropZone.value = false; </script>
SortableList
Drag.vue
<script setup lang="ts"> import { useDraggable } from '@vue-dnd-kit/core'; import { computed } from 'vue'; const props = defineProps<{ source?: any[]; index?: number; }>(); const { elementRef, handleDragStart, isOvered } = useDraggable({ data: computed(() => ({ source: props.source, index: props.index, })), }); </script> <template> <div ref="elementRef" @pointerdown="handleDragStart" > <slot /> <hr v-if="isOvered" /> </div> </template>
List
<script setup lang="ts"> import { DnDOperations, useDroppable } from '@vue-dnd-kit/core'; import Drag from 'src/components/Drag.vue'; import { ref } from 'vue'; const items = ref([ { id: 1, name: 'Item 1' }, { id: 2, name: 'Item 2' }, { id: 3, name: 'Item 3' }, ]); const { elementRef } = useDroppable({ events: { onDrop: (store) => { DnDOperations.applyTransfer(store); }, }, }); </script> <template> <div ref="elementRef"> <TransitionGroup name="sortable-list"> <Drag v-for="(item, index) in items" :key="item.id" :source="items" :index="index" > {{ item.name }} </Drag> </TransitionGroup> </div> </template> <style> .sortable-list-move, .sortable-list-enter-active, .sortable-list-leave-active { transition: all 0.5s ease; } .sortable-list-enter-from, .sortable-list-leave-to { opacity: 0; transform: translateX(30px); } </style>
Как начать использовать
Установка
# npm npm install @vue-dnd-kit/core @vueuse/core # yarn yarn add @vue-dnd-kit/core @vueuse/core # pnpm pnpm add @vue-dnd-kit/core @vueuse/core
Подключение как плагин
import { createApp } from 'vue'; import App from './App.vue'; import VueDnDKitPlugin from '@vue-dnd-kit/core'; const app = createApp(App); app.use(VueDnDKitPlugin); app.mount('#app');
Экосистема Vue DnD Kit
Важно отметить, что @vue-dnd-kit/core — это только основной пакет библиотеки, который предоставляет базовую функциональность для drag and drop. В разработке находятся дополнительные пакеты:
-
@vue-dnd-kit/utils — набор утилит для упрощения типовых сценариев
-
@vue-dnd-kit/components — готовые компоненты для быстрой интеграции (сортируемые списки, канбан-доски и т.д.)
-
@vue-dnd-kit/devtools — плагин для Vue DevTools, который позволит отлаживать состояние drag and drop в приложении
Эти дополнительные пакеты значительно упростят разработку сложных интерфейсов с перетаскиванием и будут выпущены в ближайшем будущем.
Планы на будущее
Это только начало! В планах:
-
Создание дополнительных пакетов с готовыми компонентами для типовых сценариев
-
Улучшение документации и примеров
-
Расширение возможностей для работы с вложенными списками
-
Оптимизация для еще более высокой производительности
Заключение
Vue DnD Kit — это мой вклад в экосистему Vue, который, я надеюсь, поможет разработчикам создавать более интерактивные и доступные интерфейсы, на данный момент имеет стабильный API и в дальнейшем будет улучшаться, документация уже добавлена — но будет улучшаться. Библиотека с открытым исходным кодом, и я буду рад любому вкладу от сообщества!
Репозиторий: github.com/zizigy/vue-dnd-kit
Документация: zizigy.github.io/vue-dnd-kit
Буду рад вашим отзывам и предложениям в комментариях!
ссылка на оригинал статьи https://habr.com/ru/articles/902384/
Добавить комментарий