I had used VueDraggable in my projects before, but only sparingly. One of the recent experiences taught me just how cool it was!
The Problem of Drag & Drop
There is no problem.. really.
- You drag
- You drop
- And the world goes “yeah yeah yeah”
(.. use this tone - sorry, couldn’t resist)
The problem manifests itself when that drag and drop can include any and all components. So, that’s effectively the modern web.
VueDraggable can make that problem go away in a nice way. You can almost drag any component to any component, and still live to tell that tale. Do remember though - we are talking about solving the problem of dragging external resources (like URLs, images or text ) on to our app (though a few libraries do that as well), but rather dealing with the problem of moving or copying a component of our app in “some other” (hopefully happier) place.
Get Started
Add the vuedraggable package to get started.
npm i --save vuedraggable
You can now use <draggable> component.
<draggable>
<!-- almost anything -->
</draggable>
Anything that you want to drag and drop will be contained within draggable. Let’s see a few examples to understand more.
Simple Drag & Drop
The beauty of vuedraggable is that you can drag and drop anything. Let’s try out with something simple first - text.
<draggable v-model="items" class="row">
<v-col
cols="12"
v-for="(item, index) in items"
:key="item.id"
style="font-weight:bold"
>
{{item.title}}
</v-col>
</draggable>
Write some Javascript..
new Vue({
el: "#app",
vuetify: new Vuetify(),
methods: {},
data: () => ({
items: [
{ id: 1, title: "abc" },
{ id: 3, title: "ghi" },
{ id: 4, title: "jkl" },
{ id: 5, title: "mno" },
{ id: 2, title: "def" },
],
//
}),
});
And you are done!

Vuedraggable takes care of identifying the elements, finding their boundaries, and pushing the elements to the right place after the drag & drop.
Drag & drop from one group to the other
Kanban boards are all the rage these days (huh.. kids). How about designing your own Kanban board? Just use Vuedraggable!
See the below example using Vuetify to create the grid and for some basic styling.
<div id="app">
<v-app>
<v-container>
<v-row>
<v-col cols="3">
<div style="color:red; font-weight:bold; padding-bottom:30px">Planned</div>
<draggable v-model="planned" group="kanban" tag="ul">
<li v-for="item in planned" :key="item.id" style="font-weight:bold;">
{{item.title}}
</li>
</draggable>
</v-col>
<v-col cols="3">
<div style="color:red; font-weight:bold; padding-bottom:30px">In Progress</div>
<draggable v-model="inprogress" group="kanban" tag="ul">
<li v-for="item in inprogress" :key="item.id" style="font-weight:bold;">
{{item.title}}
</li>
</draggable>
</v-col>
<v-col cols="3">
<div style="color:red; font-weight:bold; padding-bottom:30px">Done</div>
<draggable v-model="done" group="kanban" tag="ul">
<li v-for="item in done" :key="item.id" style="font-weight:bold;">
{{item.title}}
</li>
</draggable>
</v-col>
</v-container>
</v-app>
</div>
Add Javascript..
new Vue({
el: "#app",
vuetify: new Vuetify(),
methods: {},
data: () => ({
planned: [
{ id: 1, title: "abc" },
{ id: 2, title: "ghi" },
{ id: 3, title: "jkl" },
{ id: 4, title: "mno" },
{ id: 5, title: "def" },
],
inprogress: [
{ id: 6, title: "123" },
{ id: 7, title: "345" },
],
done: [{ id: 8, title: "!@#" }],
//
}),
});
You will get to this result in no time..

All we did was to specify a group name that should remain the same for all elements in the same group.
Also, did you take note that I used a different tag here?
<draggable v-model="inprogress" group="kanban" tag="ul"></draggable>
You can specify any tag to wrap around your draggable elements using tag, it is div by default. Take care to see that the draggable elements (the elements with for loop) are direct descendants of <draggable> element.
Drag & drop images
How about dragging and dropping images?

Images are just as easy as text.
<v-container>
<draggable v-model="items" class="row">
<v-col cols="12" sm="4" v-for="item in items" :key="item.id" class=".item">
<v-card class="mt-2 mb-2 item" color="grey lighten-4" flat>
<v-toolbar flat dense color="transparent" class="font-weight-bold">
{{item.title}}
</v-toolbar>
<v-img :src="item.img" height="300px"></v-img>
</v-card>
</v-col> </draggable
></v-container>
How about alternatives?
VueDraggable is based on sortable library and is fairly well documented and quite popular. You should be in safe hands for the most part. There are other libraries like -
- vue-sortable, also based on the
sortablelibrary but not as widely used - vue-drag-sortable
- Vue-Dragula: Based on Dragula, does not seem to be actively maintained anymore
However, do note a limitation of sortablejs (and VueDraggable) - it makes use of native HTML5 API for drag & drop and is subject to its constraints. You will notice this if you need to take control of every event or enable advanced functions during drag & drop.
To go beyond HTML5 API, have a look at one of the alternatives below.
- vue-grid-layout: Certainly one of the more powerful libraries for drag & drop. Quite powerful, actively maintained and it just rocks
- vue-easy-dnd: This library is fairly new but gaining rapid popularity
- Vue-smooth-dnd: offers more functionality, not constrained by HTML5 API
While the above libraries are powerful, they also need quite a bit more coding to get things going. For example, vue-grid-layout needs the exact points in x/y-axes, and element height/width.
Finis
VueDraggable is a super-friendly, and easy-to-use library. You can do much much more with VueDraggable like cloning elements, drag & drop nested elements.
See more examples of what VueDraggable can do. Use it in your own projects and go crazy!