Opinions

In the time I have delving into Vue.js I’ve come to really appreciate the framework, and its surrounding libraries.

This opinionated guide details the steps I take to start with a solid foundation for a new Vue.js project.


What particular opinions does it include?
Well, for starters:

CLI tools

  • Package manager: Yarn — Fast, reliable, and secure dependency management.
  • Project generation tool: vue-cli — CLI for rapid Vue.js development.

UI

  • UI component framework: Vuetify — Material Design component framework.
  • Material icons library: Google Material Icons — Beautifully crafted, delightful, and easy to use.
  • Validation library: Vuelidate — Simple, lightweight model-based validation for Vue.js.
  • Data visualization library: D3 — A JavaScript library for manipulating documents based on data.

Utility libraries

  • HTTP client: Axios — Promise based HTTP client for the browser and Node.js.
  • Utility library: Lodash — A modern JavaScript utility library.
  • State management pattern + library: Vuex — Centralized state management for Vue.js.
  • Date library: Moment.js — A lightweight JavaScript date library for parsing, validating, manipulating, and formatting dates.

Template and preprocessor languages

  • HTML template engine: Pug — A robust, elegant, feature rich template engine for Node.js.
  • CSS preprocessor language: Stylus — An expressive, robust, feature-rich CSS language built for Node.js.

Misc

  • Filters: vue2-filters — A collection of standard filters for Vue.js.

I have found that these tools and libraries are performant, intuitive and very easy to work with.

Browser developer tools

Last, but definitely not least:


I had a similar stack for Angular that included Angular Material plus some custom component primitives for rendering dynamic forms, data tables and other stuff.

I was really fond of the dynamic forms implementation, it allowed the user to specify highly configurable forms using a simple JSON specification.
The generated forms integrated well with our Rails JSON API backend.

I plan to write a tutorial about doing the same thing but this time with Vue.js and Vuetify, but I digress…

Setting up a new Vue.js app for success

Here we’ll see how to setup a newly created app with vue-cli so it’ll be ready for us to start hacking on it right away.

Prerequisites

Install Node.js, Yarn and vue-cli

Generate a new project

vue create my-project

My usual preset looks like this:

Vue CLI v3.0.3

? Please pick a preset:
Manually select features

? Check the features needed for your project:
Babel, PWA, Router, Vuex, CSS Pre-processors, Linter, Unit, E2E

? Use history mode for router?
(Requires proper server setup for index fallback in production)
No

? Pick a CSS pre-processor
(PostCSS, Autoprefixer and CSS Modules are supported by default):
Stylus

? Pick a linter / formatter config:
Standard

? Pick additional lint features:
Lint on save

? Pick a unit testing solution:
Jest

? Pick a E2E testing solution:
Cypress

? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.?
In dedicated config files

Adjust ESLint rules

Add this line to the rules key in the .eslintrc.js file:

'no-multiple-empty-lines': [2, { max: 2 }]

The reason for this change, is that I usually leave two consecutive blank lines between some elements inside my .js and .vue component files.

For example between import sections and following code for .js files.
Or between <template>, <script> and <style> sections for .vue files.

Install project dependencies

Let’s use the new vue add command to install Vuetify in our brand new project.

vue add vuetify

You’ll see something along the lines of:

📦  Installing vue-cli-plugin-vuetify...
✔  Successfully installed plugin: vue-cli-plugin-vuetify

? Use a pre-made template? (will replace App.vue and HelloWorld.vue) No
? Use custom theme? No
? Use custom properties (CSS variables)? No
? Select icon font md
? Use fonts as a dependency (for Electron or offline)? No
? Use a-la-carte components? No
? Use babel/polyfill? Yes
? Select locale en

🚀  Invoking generator for vue-cli-plugin-vuetify...
📦  Installing additional dependencies...
⚓  Running completion hooks...

✔  Successfully invoked generator for plugin: vue-cli-plugin-vuetify
   The following files have been updated / added:

     src/plugins/vuetify.js
     .browserslistrc
     babel.config.js
     package.json
     public/index.html
     src/main.js
     yarn.lock

After file generation, take this opportunity to run:

yarn lint

If when trying to add the latest changes to Git you’re greeted by something like:

fatal: CRLF would be replaced by LF in src/plugins/vuetify.js.

Fix it by opening that file in VSCode and change the End of Line Sequence from CRLF to LF —you’ll find the control for that near the bottom right corner.


Let’s add some project dependencies —these are the ones I always end up installing at one point or another. Customize at your leisure:

yarn add axios d3 lodash moment vuelidate

I like having the power of Stylus at my disposal when writing CSS rules.
Also, I like to write my templates using Pug.

--dev will add dependencies to the devDependencies section in your package.json file:

yarn add pug pug-plain-loader --dev

Initial app configuration and setup

To setup Vuelidate, add a src/plugins/vuelidate.js file:

import Vue from 'vue'
import Vuelidate from 'vuelidate'

Vue.use(Vuelidate)

Then, import it into your src/main.js:

// ...
import './plugins/vuelidate'
// ...

To setup vue2-filters, add a src/plugins/vue2-filters.js file:

import Vue from 'vue'
import Vue2Filters from 'vue2-filters'

Vue.use(Vue2Filters)

Then, import it into your src/main.js:

// ...
import './plugins/vue2-filters'
// ...

To see Vuetify in action, change your src/App.vue file to:

<template lang="pug">
v-app
  v-toolbar(color="primary" dark)
    v-toolbar-title Hello Vuetify!
  router-view
</template>

And change src/views/Home.vue to:

<template lang="pug">
v-content
  v-container(fluid)
    v-btn Click here!
</template>

Your src/router.js should look like:

import Vue from 'vue'
import Router from 'vue-router'

import Home from './views/Home.vue'


Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'home',
      component: Home
    }
  ]
})

Typography

The Material Design guidelines for typography, state that Roboto and Noto are the standard typefaces to use.

When you installed Vuetify through vue add vuetify it modified your public/index.html file and added these lines:

<link
  rel="stylesheet"
  href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900"
>

<link
  rel="stylesheet"
  href="https://fonts.googleapis.com/css?family=Material+Icons"
>

Have a look

Start your project with:

yarn serve

And visit: http://localhost:8080.

Running tests

To run unit tests:

yarn test:unit

To run end-to-end tests:

yarn test:e2e

As an exercise, fix those failing e2e tests!

Build your app

To build your app just type:

yarn build

The output of that command will be in the dist directory.

If you want to quickly try out your production version locally then cd into dist and type:

python -m http.server

Now visit http://localhost:8000.

Deploying to a subdirectory

When building your app for production the compiler assumes that your app is going to be deployed to /.

If that is not the case and you are deploying to /some-other-dir then you need to create a new vue.conf.js file in your app’s root directory with this content:

module.exports = {
  baseUrl: process.env.NODE_ENV === 'production'
    ? '/some-other-dir/'
    : '/'
}

You can find more info about vue.config.js here.

That’s it!
Have a good one. :)

Bonus section

Color theme tool

If you are looking for a Material Design color browser, a tool that’ll let you mix and match colors, then check this Vuetify color theme builder out!

Useful links


— lt

Feedback & comments

Get in touch on Twitter

Or by good ol' email at adriandcs@gmail.com