/ Tech

Exploring and Admiring The View (First impressions with Vue.js)

Make no mistake: I'm no front-end developer. The last time I was involved in anything that included a great deal of front-end work was about 2014. (Not that you'd know if you read my recruiter-spam.) That said, I've always had a bit of a soft spot for Javascript (I know - masochist, right?), I know my way around a CSS pre-processor like Sass or Less, and I can set up a pretty nifty front-end workflow using Gulp.

Looking inside the front-end community during the last few years though, it's become rather difficult not to feel an abject sense of pain on behalf of any new developers trying to break in to the industry; entering the field today means understanding a range of build tools, transpilers and loaders, as well as having an awareness of a plethora of libraries and frameworks.

In spite of this "framework fatigue", every now and then a real hardy library or framework comes along - and it persists, gains traction and eventually becomes something of a 'standard'. The latest project to reach this tipping point is Vue.js.

Recently I've pushed aside my - fairly extreme - preconceptions that everything Javascript involves a painfully convulated workflow, a thousand dependencies and a plethora of configuration files, and I began evaluating Vue for a mixture of client and internal work that I've got my eye on.

I must say, I was very pleasantly surprised!

Project Initialisation & Using vue-cli

As is vogue at the moment, Vue provides a command line tool to help initialise new projects. Upon installation (i.e yarn global add vue-cli) you'll be able to initialise Vue projects with just one command; complete with linting, live-reloading, CSS compilation and more.

$ yarn global add vue-cli
$ vue init webpack my-project

The second parameter to the Vue command line tool - webpack in this example - is a template. Whilst Vue provides 6 default templates - offering webpack, browserify or a more simplistic workflow - you can also write your own templates. This could be quite a useful ability if you find yourself regularly creating new projects, and perhaps relying upon a specialised boilerplate and/or internal libraries.

Whilst the presence of a CLI isn't unique - Ember for instance has had Ember-CLI since around 2013 - and it wouldn't be the sole reason for selecting a framework, the productivity boost associated with not having to manually configure the toolchain is immense. As I previously mentioned, I really dislike the front-end tooling - so for me, the Vue CLI is immensely useful.

Integrating Vue on an existing project

Vue describes itself as "incrementally adoptable", meaning that it can be integrated in to existing projects - and you're free to use Vue as little or as much as you want. Consider this traditional "Hello World":

<html>
  <head>
    <title>Hello Vue.js</title>
    <script src="https://unpkg.com/vue"></script>
  </head>
  <body>
    <div id="vue">
      <span class="greeting">{{ message }}</span>
    </div>
  </body>
  <script>
    var app = new Vue({
      el   : '#vue',
      data : {
        message: 'Hello, from Vue!'
      }
    });
  </script>
</html>

There's two things that are worth some special attention in this example:

  1. The Vue component is little more than a standard Javascript object that's been passed as an argument to a new Vue instance.
  2. Vue is localised entirely to it's root component, in this case '#app' - allowing it to be integrated with existing sites/apps with ease.

It's worth noting that by manually pulling in Vue - like in this example - you wont have a lot of the nice features that the Vue cli configures for you - such as asset compilation, live-reload, dependency management and so on. Alas, if you're manually implementing Vue then there's a good chance that you have an existing workflow to deal with these areas.

Writing Components & Using .vue files

Broadly speaking, there are three components to any front-end project: markup, stylesheets and scripts. Vue components are no different, with a templating syntax akin to a combination of Handlebars and Angular directives, component logic written in Javascript, and the obligatory styling for the browser.

One of the beauties of using a component based framework like Vue or React, is that components can be viewed as self-contained little black boxes. The benefits of having individual self-contained units are limited if each unit requires code spread over the entirety of your codebase though, and that's where Vue's Single File Components come in.

A "Single File Component", or .vue file, contains everything required for a fully functioning component: the template, the logic, and the styling. Here's our Hello World above written as a SFC:

<template>
    <span class="greeting">{{ message }}</span>
</template>
    
<script>
    export default {
        data () {
            return {
                message: "Hello, from Vue!"
            }
        }
    }
</script>
    
<style lang="scss" scoped>
    span.greeting {
       color: green;
    }
</style>

In this example we can also see the "Scoped CSS" functionality that Vue can provide, whereby the CSS included in a .vue file will be limited to those components only. Behind the scenes this is done by applying unique attributes to the component elements, and prefixing CSS rules with a data-attribute selector. (i.e [component-102321])

State Management & Using Vuex

To say I was completely unfamiliar with the concepts behind Vue would be a little unfair; around a year ago I'd spent two weeks working on a project that required delving in to a React.js based Single Page Application (SPA) - complete with the Redux state container.

With this in mind, the concepts behind using Vuex for state management weren't too daunting - although I do remember quite a bit of confusion when I initially used Redux. I suggest reading up on Facebook's Flux architecture prior to diving in to deeply with Vuex; the documentation is actually very good.

Once the theory is out of the way, the practicalities of working with Vuex are very straightforward - although it can be quite boilerplate-heavy depending upon how you structure your codebase.

Vue's brilliant DevTools allows you to inspect the state stored in Vuex, as well as the state of individual components. Being able to take a real time peek in to the state container proved invaluable whilst evaluating Vue.

Routing & Using vue-router

When architecting an SPA, you'll very quickly hit the brickwall of routing via an individual page; and this is where your router comes in. Just like a backend router, a JS one will parse the current URL and determine which view should be loaded. Unlike MVC frameworks - i.e Ember and Angular - Vue doesn't require a router by default, as its use case is generally for developing and deploying individual front-end components, not entire applications.

That's not to say that you can't develop a Single Page Application, nor that there isn't a router available. vue-router is a plugin that provides routing functionality to Vue apps; but whilst I've wrote a few components now, I've yet to really delve in to this functionality too deeply. From initial experiments though, the Vue Router provides a very clean interface - via two components.

The first component is router-link, and this can be viewed as quite similar to a normal HTML a element; it accepts a URI and provides you a hyperlink in return, allowing you to set the text of the hyperlink. For example:

<router-link to='/your-path'>Link</router-link>

The second component is router-view, and this allows the router to know where the routed content should be displayed. This is best viewed as a simple container which will be populated with the component that matches your URL. For example:

<router-view></router-view>

The API for configuring the router is just as simple too:

Vue.use(VueRouter);

const router = [
    // A route is simply a map where 'path -> component'
    { path: '/welcome', component: Welcome },
    // Dynamic routes are allowed too. For example, the below will match URLs like /hello/fergus, or /hello/francesca
    { path: '/hello/:name', component: SayHello }
];

const app = new Vue({
    ...
    router
});

You can do a lot more with the router, such as the rather interesting concept of named views - whereby you may have router-view components and associate multiple view components to a single URI. It's also clear to see that the router could be used outside of the traditional idea of a SPA, and could be quite useful for building interfaces whereby an individual page may be responsible for multiple items; i.e document stores or portfolios.

The Vue Ecosystem and Community

When evaluating a technology choice, it would be remiss not to consider the community around that technology. With both a wide variety of compatible packages, an active (and friendly) community, and a healthy development cycle - Vue ticks all the boxes here.

A cursory glance at Awesome Vue list on Github shows some of the best components and resources that the community has to offer.

Conclusion

I really enjoyed writing Vue components; it's simple and concise both conceptually and practically, and whilst multi-component state management via Vuex may seem strange to those unfamiliar - it does have clear advantages.

For specific use cases - such as the incremental modernisation of an existing/complex site or application - I can see it performing very well. Similarly, the development of stateful UI widgets can also simplified heavily via Vue's component model.

I'd personally be reluctant to recommend Vue, or React for that matter, when building a fully fledged SPA; instead opting for a framework such as Ember or Angular that has been designed with that intention from the ground up. Many successful projects do this, and it does work. Having had the experience of working on SPAs built with both React and Angular though, I know I'd opt for the full framework in most cases.


Fergus

Contract Software Developer and DevSecOps Consultant, based out of London in England. Interests include information security, current affairs, and photography.