Upcoming Course: Code Your Own Business w/ React + GraphQL!
We're live-coding on Twitch! Join us!
Build a Single Page Time Tracking App with Vue.js: Introduction

Build a Single Page Time Tracking App with Vue.js: Introduction

Vue.js is simple. It is so simple that people often dismiss it as only suitable for small projects. While it is true the Vue.js core is just a view layer library, there are in fact a collection of tools that will enable you to build full-blown, large-scale SPAs (Single Page Applications) using Vue.js with a pleasant development experience.

If you are already familiar with the basics of Vue.js but feel that the world of SPA is scary, this series is for you. We will first introduce the concepts, tools and libraries needed in this first article, and then will walk you through the full process of building an example app in the rest of the series.

First Thing's First: What is a SPA?

Single-Page Applications (SPAs) are web apps that load a single HTML page and dynamically update that page as the user interacts with the app. SPAs use AJAX and HTML5 to create fluid and responsive Web apps, without constant page reloads.

As stated in the above description taken from Wikipedia, the main advantage of SPAs is that the app can respond to user interactions without fully reloading the page, resulting in a much more fluid user experience.

As a nice side effect, a SPA also encourages the backend to focus on exposing data endpoints, which makes the overall architecture more decoupled and potentially reusable for other types of clients.

From the developer's perspective, the main difference between SPAs and a traditional backend-rendered app is that we have to treat the client side as an application with its own structure. Typically we will need to handle routing, data fetching and persistence, view rendering and the necessary build setup to facilitate a modularized codebase.

The Building Blocks

For a Vue.js-based SPA, here are the tools and libraries that we will use to fill in these gaps:

Essential Reading: Learn React from Scratch! (2019 Edition)
  • View Layer: Vue.js, of course :)

  • Routing: vue-router, the official router for Vue.js.

  • State Management: vuex, a state-management solution inspired by Flux/Redux, but designed specifically for Vue.

  • Server Communication: vue-resource, plugin for interfacing with a RESTful backend.

  • Build Tool: Webpack + vue-loader for modules, hot-reloading, ES2015, pre-processors and most importantly, single-file Vue components.

Let's take a closer look at each part.

The View Layer

This series assumes you are already familiar with the basics of Vue.js. If you are not, you should be able to quickly pick it up by going through official guide and other tutorials available.

The core concept when using Vue.js for large SPAs is dividing your application into many nested, self-contained components. We also want to carefully design how these components interact with one another by leveraging component props for the data flow and custom events for communication. By doing so, we dissect the complexity into small, decoupled units that are tremendously easier to maintain.


The official vue-router library handles client side routing, and supports both hash mode and HTML5 history mode. It is a bit different from standalone routing libraries in that it deeply integrates with Vue.js and makes the assumption that we are mapping nested routes to nested Vue components.

When using vue-router, we implement components that serve as "pages", and within these components we can implement hook functions that are called when the route changes.

State Management

State management is a topic that only arises when your application's complexity grows beyond a certain level. When you have multiple components that need to share and mutate application state, it can get very hard to reason about and maintain if you don't have a layer in your application that is dedicated to managing such shared state.

This is where Vuex comes in. You don't necessarily need Vuex if you application is relatively simple - but if you are interested, here's an excellent intro on what problem it solves by Anirudh Sanjeev.

Server Communication

We will be working with a RESTful backend in the example, so we are using the vue-resource plugin which is maintained by the PageKit team. Do note that Vue.js SPAs are backend-agnostic and can basically work with any data fetching solution you prefer, for example fetch, restful.js, Firebase or even Falcor.

Build Tool

This is probably the biggest hurdle that you'll have to jump through if you are not familiar with the frontend build tool scene, and we will try to explain it here. Feel free to skip this section if you are already experienced with Webpack.

First, the entire build tool chain relies on Node.js, and we will be managing all our library and tool dependencies using NPM. Although NPM started out as the package manager for Node.js backend modules, it is now widely used for frontend package management too. Because all NPM packages are authored using the CommonJS module format, we need special tooling to "bundle" these modules into files that are suitable for final deployment. Webpack is exactly such a tool, and you may have also heard of a similar tool called Browserify.

We will be using Webpack for the series because it provides more advanced functionalities out of the box, such as hot-reloading, bundle-splitting and static asset handling.

Both Webpack and Browserify exposes APIs that allows us to load more than just CommonJS modules: for example, we can directly require() an HTML file by transforming it into a JavaScript string.

By treating everything for your frontend including HTML, CSS and even image files as module dependencies that can be arbitrarily transformed during the bundling process, Webpack actually covers most of the build tasks that you will encounter when building a SPA. We are primarily going to build the example using Webpack and plain NPM scripts, without the need for a task runner like Gulp or Grunt.

We will also be using vue-loader which enables us to author Vue components in a single file:

// app.vue
  <h1 class="red">{{msg}}</h1>

export default {
  data () {
    return {
      msg: 'Hello world!'

.red {
  color: #f00;

In addition, the combination of Webpack and vue-loader gives us:

  1. ES2015 by default. This allows us to use future JavaScript syntax today, which results in more expressive and concise code.

  2. Embedded pre-processors. You can use your pre-processors of choice inside single-file Vue components, for example using Jade for the template and SASS for the styles.

  3. CSS output inside Vue components are autoprefixed. You can also use any PostCSS plugins you like.

  4. Scoped CSS. By adding a scoped attribute to the <style>, vue-loader will simulate scoped CSS by rewriting the template and style output so that the CSS for a specific component will not affect other parts of your app.

  5. Hot Reload. When editing a Vue component during development, the component will be "hot swapped" into the running app, maintaining the app state without having the reload the page. This greatly improves the development experience.

Setting it Up

Now with all these fancy features, it could be a really daunting task to assemble the build stack yourself! Luckily, Vue provides vue-cli, a command-line interface that makes it trivially easy to get started:

npm install -g vue-cli
vue init webpack my-project

Answer the prompts, and the CLI will scaffold a project with all the aforementioned features working out of the box. All you need to do next is:

cd my-project
npm install # install dependencies
npm run dev # start dev server at http://localhost:8080

For full details on what is included in the generated project, check out the project template documentation.


We haven't really written any real app code so far, but I hope we have got you excited about learning more. In the next article, Ryan Chenkie will start taking us through a series of building a full-fledged SPA using this stack. Stay tuned!

Like this article? Follow @youyuxi on Twitter