Creating a kanban-style task management app with Vue.js
Nulab
December 02, 2018
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:
- Scaffolding a basic Vue app
- Filter tasks by status
- Creating task card components
- Creating the status change process
- Creating an Add Task function
- Adding transitions when the status changes
- Conclusion
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.
You 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.
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.
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.