Over the past six months I’ve had the opportunity to work on a simple PWA using Vue. To speed up the learning curve we brought in Eduardo San Martin Morote, a Vue core contributor, to help us on the project. If you ever get the chance to hire someone who is an expert in their domain for your project, I recommend it! It’s been really valuable learning while collaborating and you get an opportunity to shortcut some of the learning the long, hard, stupid way and starting with a good foundation of best practices.
I’m enjoying Vue and thought I’d compile a simple list of the things I like about it. So here’s what I like about writing an app in Vue…
Vue’s component authoring coincides with how I author components
The outline of a Vue component in a .vue
file is practically a direct mapping to how I enjoy authoring components in my brain.
<template>
<!-- Start with a foundation of good HTML markup -->
</template>
<script>
// Add interaction with JavaScript
</script>
<style>
/* Add styling as necessary. */
</style>
I really enjoy this methodology as it maps to my sensibilities but it also adds a layer of predictability when opening a Vue component. I find this structure gives components a nice linear reading experience, similar to a Web Component. Markup, styles, and script concerns are all separated nicely.
I’ve come to realize one thing I don’t particularly like about React is jumping into a file, reading the top for the state, jumping to the bottom to find the render
function, then following the method calls up to a series other sub-rendering functions only to find the component I’m looking for is in another castle. That cognitive load is taxing for me.
Vue has built-in template directives like v-for
and v-if
that I really enjoy. For me it speeds up the templating process quite a bit and relieves a lot of need for those sub-rendering functions. Reading markup has a very linear flow.
I understand framework-centric directives are a somewhat polarizing feature because your component isn’t “just JavaScript” anymore. One nice thing about Vue is that if you prefer a more JS-centric approach, it gives you that as well:
Vue.component('my-component', {
// render template
template: `<div>HTML goes here</div>`
})
Style is handled in a normal CSS file or you can leverage Vue’s data()
and computed()
methods to homeroll you own CSS-in-JS solution. I actually use the JS-only approach quite a bit when I want to play around with Vue without using a build process, which leads me to…
You can use Vue without a build process
I’ve found Vue really useful for experimenting with ideas quickly in an environment like CodePen.
<div id="app">
{{ message }}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
</script>
I set up a CodePen template to make it easier for me to prototype ideas for reactive applications. For one client, I was able to replicate ~600 lines of jQuery spaghetti in ~40 lines of Vue. It felt empowering to get an idea up and running so quickly.
That’s not to say other frameworks can’t do this. I’ve seen tutorials where people use React without JSX which would allow you to skip a build step, however, every time I see that it feels disingenuous because that’s simply not how people use React. Usually there’s a lot more to it.
For me, “buildless” processes are great because they’re a lower barrier to entry, easier learning, and easier to integrate into existing applications. Which leads me to…
Vue can graft into existing server side applications
While talking to Evan You on Shop Talk I became impressed by the design decision to remove a build step requirement in Vue. Upgrading legacy applications was one of the usecases Vue was designed around. It means that developers can piecemeal upgrade bits of an application as necessary.
In my experience Angular, React, and a lot of other frameworks ultimately require you to go all in early and establish a large toolchain around these frameworks. Angular prescribes a lot with its amazing CLI. React on the other hand doesn’t prescribe anything, but requires you to self-assemble and wield a somewhat complex toolchain. But as Evan put it in his JSConf Asia talk, Vue sits in the middle of the “Cathedral and the Bazaar”. Vue has useful tooling, but it’s all optional and you can use only what you need. In some ways, Vue’s grafting capabilities really does make it seem like a jQuery replacement you can drop in to give your components superpowers as needed.
I’ve been working on a legacy Java application for the last couple years and though the team ultimately chose Angular for its front-end refactor, in the back of my mind I think Vue may have been a more suitable choice. We could approach the refactor bit-by-bit rather than a whole-hog refactor. It probably would have helped gain some momentum.
Another way to gain momentum is leveraging the plugins in Vue’s excellent plugin ecosystem, which leads me to…
Vue’s first-party plugins and the plugin ecosystem are excellent
The nature of my client-services business is that I bounce around through a few technologies: a legacy Java project, a couple Angular projects, a CraftCMS project, some WordPress sites, multiple Jekyll projects, a Fractal project, a couple Eleventy projects, and a Vue project. This context switching leaves me with little time to keep up on framework zeitgeist. One thing that I’ve come to appreciate about Vue is it’s first party plugins and it’s plugin ecosystem.
For common app building problems like State Management or Routing, Vue goes the extra mile and provides first-party solutions. Global state is handled by Vuex, an approach based on Redux. Routing is handled by Vue Router. These are all subdomains off the main Vue site.
You can go off the beaten path, sure, but as someone with limited time to invest in rogue technologies I simply can’t afford to spend hours searching npm for the last few projects I’ve heard about. No more investigating random libs and starting down a path only to realize it’s not for me.
One unique thing about the Vue community is every plugin and project page has as “Sponsorship” tier. The Vue community has done an amazing job normalizing contributions. As an inconsistent Vue user, this gives me confidence that any plugin or project I use will be around 6 months later when I need it again.
Overall, this healthy plugin ecosystem allows me to save the cognitive load of Keeping Up With Vue and if I crave even more conventions, then there’s Nuxt…
Nuxt for more better conventions
Nuxt is a Vue-based app building framework that essentially collects all of the first-party plugins and adds a few conventions (like directory structure naming) and server-side rendering. Nuxt and the Nuxt Community seem to optimize for supporting common app building scenarios and have plugins for Axios, Authentication strategies, PWAs and a whole bunch more.
When you start a Nuxt project, it looks a lot like this:
my-project
├── assets // assets that get compiled go here
├── components // components go here
├── layouts // layouts go here
├── middleware // middleware (whatever that is) goes here
├── pages // pages go here
| ├── posts // RESTful resource routes
| | ├── _id.vue
| | └── index.vue
| └── about.vue // single views
├── server // server stuff goes here
├── static // static files go here
├── store // state management goes here
└── nuxt.config.js // configure nuxt here
This folder structure is comfortable for me because it looks almost EXACTLY like a Jekyll project, which was handy because (other than linter complaints) it made converting a Jekyll prototype into a Nuxt project a breeze.
There are tiny conveniences here too. Anything in pages/
automatically gets a route created and even supports RESTful param based routing as well. Anything in store/
automatically gets added to Vuex. Smart defaults and tiny conveniences I never knew I needed.
People might hate this comparison, but if Vue is like Ruby, then Nuxt is like Rails. I mean that in the best way possible. Nuxt allows you to focus on app building in a predictable way rather than stringing together a bunch of haphazard pieces of code.
In summary, I like Vue quite a bit.
Vue checks most, if not all, the boxes for me. It suits a lot of my sensibilities and preferences and I feel like I can embrace “convention over configuration” without inheriting a lot of technical debt. It feels like a pair of shoes I could see myself buying or a t-shirt that fits my body type. It’s an intangible feeling and hard to explain.
I do have some distant concerns like Web Component compatibility and some Accessibility related items, but I’m sure between the core team and the community those issues will be sorted out. I only mention those things to make this review seem less glowing.
This review is pretty basic. It’s also incomplete and doesn’t cover well loved features like built-in transitions and the CLI. I look forward to exploring those features more. Overall, I feel like Vue’s intentional design and out-of-the-box experience is really useful and makes me feel powerful as a developer… And isn’t that what matters most!