Creating a kanban-style task management app with Vue.js

Creating a kanban-style task management app with Vue.js

As a developer for Backlog, my work usually revolves around Scala and Java, but I like pretty much all dynamically typed languages, like Ruby and JavaScript. Lately, I’m interested in front-end development and have been experimenting with Vue.js in my spare time.

Vue bills itself as a progressive framework. I really like it because you can start implementing it on a small scale project at first and then, as your software grows, you can integrate it with other libraries to power large and highly complex applications. There’s also a ton of documentation out there, so it’s pretty easy to pick up, and if you’re coming from a different framework and want to know how Vue compares to it, their comparison page is very detailed and should give you all the information you need.

Today, we’re going to use Vue to create a simple Kanban-style task management app. We will cover the following:

I chose Bulma for the CSS framework because it’s written by Jeremy Thomas, author of Web Design in 4 Minutes.

Below is a screenshot of what the finished app will look like. The cards that show each task are arranged vertically by status: Open, In-Progress, and Completed. The cards display the team member assigned to complete each task and the number of hours needed to complete that task.

Creating a kanban-style task management app with Vue.jsYou can find the complete source code on JSFiddle.

Scaffolding a basic Vue app

To get started, we need to prepare the entry html file and load Vue.js and Bulma libraries.

⚠️ Please note that in this article as well as in the sample application we are using:

  • Vue.js version 2.5.2 (https://unpkg.com/vue@2.5.2/dist/vue.js)
  • Bulma version 0.6.0 (https://cdnjs.cloudflare.com/ajax/libs/bulma/0.6.0/css/bulma.min.css)

Next, we will create a Vue instance that will serve as root of our application. In the options object passed to the instance, we use el to specify the DOM element the instance is plugged into and data to describe the data that will be handled within the app.

Once the root instance is in place, we can create a template to display its data. In Vue we use an html-based template syntax.

The HTML element specified by id=“board” is the DOM element managed by the Vue root instance we created earlier. This element is bound to that instance’s data, which allows us to reference the data directly from the template. The Vue templating syntax provides us with different mechanisms of accessing the underlying instance data, such as interpolations, directives, and so on. In our template, we’re mainly using the double curly braces syntax {{}} and the v-for directive.

The styles associated with this template are as follows:

Here is our progress so far:

Filter tasks by status

This all looks great, but without taking the status of a task into account, all the tasks will be rendered in the “Open” column. Let’s fix that and filter the tasks by status!

First we’ll define the filter functions that return all tasks with a given status:

To make use of these functions from the Vue instance, we’ll extend the instance’s options object with the computed property and expose them as computed properties. This way we have the guarantee that whenever the underlying tasks data changes, all the bindings that depend on our computed properties will be updated as well.

Now we can update our template to make sure that only open tasks are rendered in the “Open” column

which will look like this:

Creating task card components

Next, we want to be able to display our tasks in different columns, but if we simply copy and paste the class=“card” element we’ll have to make manual adjustments to each copy.

For such use cases, Vue comes with a built-in Component function, which makes it easy for us to build reusable parts. Let’s see how we could use this concept to build a task-card component.

We’ll start by extracting the html under `class=“card”` to a separate template and assign it to the template property. The props property will be used to transfer the data to the task-card component.

That’s all it takes! Now our task-card component is ready to use

With v-bind:task=“task”, the task data is passed to the task-card component’s props. By using the Component function, we hide the task-card implementation details from the board template, making the code much easier to read.

Creating the status change process

As the screen is now mostly complete, let’s add the functionality of changing a task’s status. For that we will define a couple of methods for increasing and decreasing a task’s status value, and make sure that clicking the ◀︎▶︎ at the bottom of each task-card will invoke the correct method. For the click event handlers we will use the v-on directive.

Now we can change the status of a task with just one click.

Creating an Add Task function

In order to use this app as an actual task manager, we need to create an “Add Task” function. All we have to do is create an input form and the appropriate JavaScript function.

To get started, let’s add the newTaskName, newTaskAssignee, and newTaskEffort properties to the Vue instance data and bind each of them to its corresponding form input. The addTask function can be defined as a property on the methods object.

Next we’re going to add an input form in the app template and use the v-model directive to bind those new properties we created to their corresponding inputs. By doing this, we can reflect changes of the input values back to the Vue instance data.

Now we can finally add tasks.

5 - Creating an Add Task function

Adding transitions when the status changes

Although we can now change the task’s status and add new tasks, the DOM updates very quickly and it is hard to tell what has happened. By using the Transition function in Vue, we can add animation effects for DOM updates.

We can define the style in css and wrap the parts we want this transition to apply to with the transition tag in the html template. This allows us to add an effect when the DOM updates. Since we are using the v-for directive for displaying the items in the list, we’re going to use the transition-group tag.

By using Transition, it is easy to tell which DOM element has changed when the status is updated.

*The length of the effect has been slowed for demonstration purposes.

6 - Adding transitions when the status changes

Conclusion

In this article, we looked at how you can use Vue to create a kanban-style task management app. The demo application we built is fairly basic but serves as a good base to build on for more complex features. With a little more work, you could go on to store data on the back-end and componentize the columns.

If you followed along with this tutorial, share your work with us on Twitter! And let us know what you thought of Vue.

Takahiro Hisaki Takahiro Hisaki is a software developer for Nulab currently based in Tokyo.