How to Use The Vue Draggable Library to Create an Interactive Kanban Board

Written by samwalpole | Published 2021/02/11
Tech Story Tags: vue | vuejs | javascript | tutorial | drag-and-drop | kanban | components-with-vue | programming | web-monetization

TLDR Vue Draggable is a great library for Vuejs that makes it super simple to create interactive draggable components with virtually no effort. I have recently used it to create an interactive kanban board, in which tasks can be rearranged and moved between cards just by dragging. I'm using Vuetify as the UI framework, in case the tags look unfamiliar. P.S. I'm also writing a tutorial on how to use VueDraggable to create reorderable cards.via the TL;DR App

Vue Draggable is a great library for Vue.js that makes it super simple to create interactive draggable components with virtually no effort. I have recently used it to create an interactive kanban board, in which tasks can be rearranged and moved between cards just by dragging.
So let's start by creating some reorderable cards!
P.S. I'm using Vuetify as the UI framework, in case the tags look unfamiliar.
<template>
  <v-container fluid>
    <v-row>
      <v-col class="text-right">
        <v-btn color="primary" depressed @click="addCard"> Add Card </v-btn>
      </v-col>
    </v-row>
    <v-row>
      <v-col v-for="(card, i) in cards" :key="i" cols="12" sm="6" md="4">
        <v-card outlined>
          <v-card-title>
            <v-text-field v-model="card.title"></v-text-field>
          </v-card-title>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
export default {
  data: () => ({
    cards: []
  }),  
  methods: {
    addCard() {
      const card = {
        title: 'New Card',
        tasks: [],
      }

      this.cards.push(card)
    },
  }
}
</script>
The code above should give you the ability to create cards by clicking the Add Card button, but they aren't draggable yet.
First, make sure that you have VueDraggable installed by running:
<script>
import Draggable from 'vuedraggable'

export default {
  components: {
    Draggable,
  },
  data: () => ({
    cards: []
  }
Finally, all we need to do to make the cards draggable is to wrap the cards with the draggable component. In our case, we're replacing v-row with draggable.
<draggable :list="cards" group="cards" class="row">
  <v-col v-for="(card, i) in cards" :key="i" cols="12" sm="6" md="4">
...
There are two attributes that are important to note. First, the list attribute defines the list of objects that should be draggable, in our case the cards array. Secondly, the group attribute is just a way of identifying groups of draggable components (you'll see why this is useful when we move on to creating draggable tasks).
Try running your project now. You should be able to create multiple cards, and reorder them by dragging!
Now let's move on to the tasks. Below the v-card-title tag we need to add the following code:
<v-card-text>
  <draggable :list="card.tasks" group="tasks" class="row">
    <v-col v-for="(task, j) in card.tasks" :key="j" cols="12">
      <v-text-field v-model="task.title">
        <template v-slot:append>
           <v-btn color="error" text class="ml-3" @click="deleteTask(i, j)"> Delete </v-btn>
        </template>
      </v-text-field>
    </v-col>

    <template v-slot:footer>
      <v-col cols="12">
        <v-btn color="primary" depressed block @click="addTask(card)"> Add Activity </v-btn>
      </v-col>
      <v-col cols="12">
        <v-btn color="error" text block @click="deleteCard(i)"> Delete Card </v-btn>
      </v-col>
    </template>
  </draggable>
  </v-card-text>
Add the following in the script section:
methods: {
    deleteCard(index) {
      this.cards = [...this.cards.slice(0, index), ...this.cards.slice(index + 1)]
    },
    addTask(card) {
      const task = {
        title: 'New Activity'
      }

      card.tasks.push(task)
    },
    deleteTask(cardIndex, taskIndex) {
      const card = this.cards[cardIndex]
      card.tasks = [...card.tasks.slice(0, taskIndex), ...card.tasks.slice(taskIndex + 1)]
    }
}
Here we've added the ability to add and delete tasks from each card, as well as delete the card itself. We've also added another draggable component, which wraps around each group of tasks. We've given it a group name of tasks. This is important because each list of tasks will have the same group name, meaning that we can drag tasks from one card to another! P.S. if you only wanted tasks to be reorderable within its own card, you would have to create a unique group name for each list of tasks.
And that's it! Hopefully, this post has shown you how quick and easy it is to develop highly interactive draggable apps using the Vue Draggable library. What ideas will you use it for?

Conclusion

In this post, I have shown you the basics of using the Vue Draggable library to create an interactive kanban board. The full repository can be found here on GitHub.
I post mostly about full stack .NET and Vue web development. To make sure that you don't miss out on any posts, please follow this blog and subscribe to my newsletter. If you found this post helpful, please like it and share it. You can also find me on Twitter.

Written by samwalpole | Fullstack .NET and JavaScript web developer. Coding teacher and advocate
Published by HackerNoon on 2021/02/11