A powerful and flexible drag & drop library for Vue.js applications with TypeScript support.
-
π― Simple Composables API
- Intuitive hooks-based approach
- Clean and declarative syntax
- Minimal boilerplate code
-
π¨ Full Customization
- Custom drag overlays
- Flexible styling system
- Animation support
- Custom drag handles
-
π± Advanced Input Support
- Touch devices support
- Mouse events
- Multi-touch gestures
-
β‘ Optimized Rendering
- Virtual DOM friendly
- Minimal re-renders
- Efficient DOM updates
- Memory leak prevention
-
π Smart Auto-scrolling
- Smooth scroll animations
- Configurable thresholds
- Performance-optimized
- Works with nested scrollable containers
-
π TypeScript Ready
- Full type coverage
- Type inference
- IDE autocompletion
- Type-safe events
-
π Layout Features
- Grid system support
- Flex layout compatible
- Responsive design ready
- Dynamic constraints
-
π― Smart Grouping
- Element groups
- Zone filtering
- Nested groups
- Dynamic group validation
-
π Rich Events System
- Comprehensive lifecycle events
- Custom event handlers
- Drag state tracking
- Position coordinates
-
π‘οΈ Built-in Utilities
- Geometry calculations
- Bounding box tracking
- Position management
- Intersection detection
- π Framework Integration
- Vue 3 Composition API
- Nuxt.js compatible
- Works with SSR
- Plugin ecosystem ready
Choose your preferred package manager:
npm install vue-dnd-hooks
yarn add vue-dnd-hooks
pnpm install vue-dnd-hooks
π Root Application Component
<script setup lang="ts">
import { ref } from 'vue';
import { DragOverlay } from 'vue-dnd-hooks';
import Draggable from './components/Draggable.vue';
import Droppable from './components/Droppable.vue';
const handleDrop = () => (elementInDropZone.value = true);
const handleEnd = () => (elementInDropZone.value = false);
const elementInDropZone = ref<boolean>(false);
</script>
<template>
<div>
<Draggable v-if="!elementInDropZone"> drag me </Draggable>
<Droppable @drop="handleDrop">
<Draggable
v-if="elementInDropZone"
@end="handleEnd"
>
im in drop zone
</Draggable>
</Droppable>
<DragOverlay />
</div>
</template>
𧩠components/Draggable.vue
<script setup lang="ts">
import { useDrag } from 'vue-dnd-hooks';
const emit = defineEmits<{
(e: 'end'): void;
}>();
const { elementRef, handleDragStart, isDragging } = useDrag({
events: { onEnd: () => emit('end') },
});
</script>
<template>
<div
ref="elementRef"
@pointerdown="handleDragStart"
:class="{ dragging: isDragging }"
>
<slot />
</div>
</template>
<style scoped>
.dragging {
opacity: 0.5;
}
</style>
𧩠components/Droppable.vue
<script setup lang="ts">
import { useDrop } from 'vue-dnd-hooks';
const emit = defineEmits<{
(e: 'drop'): void;
}>();
const { elementRef, isOvered } = useDrop({
events: { onDrop: () => emit('drop') },
});
</script>
<template>
<div
ref="elementRef"
:class="{
droppable: true,
'is-overed': isOvered,
}"
>
drop here
<slot />
</div>
</template>
<style scoped>
.droppable {
width: 100px;
height: 100px;
border: 1px solid black;
}
.is-overed {
background-color: #f0f0f0;
border: 1px dashed red;
}
</style>
(Not Ready)
We welcome contributions! Please read our [contributing guidelines](CONTRIBUTING.md) before submitting pull requests.
- File upload with drag & drop
- React port (probably not, react have dnd-kit)
- Accessibility improvements (ARIA)
Projects using Vue Drag & Drop Library:
- Project Name - Brief description
- Your Project Here - Submit your project!
If you find this library helpful, please consider:
- Giving it a star on GitHub β
- Sharing it with others
Made with β€οΈ for the Vue.js community