Posted on June 1, 2017 by rodney
Tags: nerd

I have done a few projects at work with Vue.js and we consider it to be a very good frontend framework. Unfortunately, using JavaScript for frontend code is still a necessary evil. So the goal is to pick something sensible which integrates well with non-JavaScript code.

What you absolutely must avoid are frontend libraries for direct manipulation of the DOM – i.e. jQuery. Unless you’re extremely careful, it will end up as a big mess. It’s only “more simple” in very simple app. One alternative to jQuery is frameworks which offer either two-way data binding or functional declaration of views.

I have previously used Angular.js v1, which I consider to be quite good in many cases. One of its major disadvantages is the use of complicated “dependency injection,” which has no place in a dynamic language like JavaScript. Also, early versions lacked component-style directives, which have turned out to be a good design pattern.

Vue.js is basically like Angular minus the bad ideas. The API is ergonomic and quite well documented. Here is a collection of random advice I have after working with Vue.js for a while.

1. Start using it now

Start using Vue.js ASAP. Do not “just make something” with jQuery and then convert to Vue once it gets too messy. It will be a pain to convert your code as you move from the imperative to declarative model.

Note that jQuery manipulation can ne used within components but not the other way around. The component model is more powerful.

2. More simple than you think

It is extremely simple to add Vue into your web page. Possibly it won’t be necessary to even create any components.

3. Keeping templates in HTML without build system

Templates can be defined in the HTML using

<script type="text/x-template" id="tmpl-id"></script>

Refer them with { template: "#tmpl-id" }.

This method can be advantageous when not using the recommended JS build system(s) e.g. gulp/webpack. (these normally collect html templates and embed them in the minified JavaScript).

The benefit of this style that your templates won’t clutter the JavaScript. The HTML file may get long but just keep it organised and use a matching name for templates to their components.

4. Nothing changing? Remember data()

Any data that needs to be reacted upon must be defined in the component data() function. If you’re wondering why the view doesn’t change when data changes, then it’s probably because of this.

If you have nested objects in your data, then these objects with all relevant properties also need to be present in the component data() function. You might need to write a utility function to generate a blank object for this purpose.

Component props don’t need to be put in data().

5. Making your own v-model

You can add v-model to your components by adding a "value" property and emitting the "input" event. Since v2.2 it’s possible to configure what these names are for each component (useful when using <input type="checkbox">).

6. Don’t forget to bind

Don’t forget to add v-bind when using variables with component properties. E.g. this won’t work. <my-component myproperty="myVariable">

7. Event names all lowercase

Events must be all lowercase letters. Other things don’t work (I think).

8. Data watching is a necessary evil

Data watches are a necessary evil when doing jQuery manipulation or wrapping other JavaScript widgets. By default it uses reference equality but deep watching is also possible using { myproperty: { handler() { }, deep: true } }.

9. Accessing specific DOM elements within component template

For wrapping other JavaScript libs, e.g. bootstrap modals, the $refs feature is handy. You can easily get access an element within the template by naming it with <div ref="name">.

10. Use `backtick` strings for templates

When embedding small templates in JavaScript, always use backtick `strings` to get easy quotation and multi-line strings.

11. Never write function()

For methods, life-cycle hooks, etc, you need to use the this variable to access the component. So these methods need to be old-style function() { }.

Anywhere else you need a function, use the () => arrow syntax so it doesn’t rebind “this”.

Use the function shortcut syntax for Vue component methods, e.g.

const myComponent = {
    data() {
        return { prop: "value" };
    },
    methods: {
        myMethod() {
          window.alert(`Hello: ${this.prop}`);
        }
    },
    // ...
}

Then you can search your JavaScript for the “function” keyword – and anywhere it exists is probably a bug. I repeat, anywhere “function” is used when it’s not for the purpose of rebinding “this” is a bug.

12. Doesn’t work on <body> element

I never found it possible to start Vue on the <body> element. It seems necessary to use something beneath that level.

13. Lost all but the first element of the template?

Templates always need one single element. So you have to wrap everything in a <div> or whatever. Otherwise you lose all but the first element in the template.

14. Angular.js-style controller

To make a component which is sort of equivalent to an Angular.js controller, set the template to <div><slot></slot></div>.

15. Private variables/methods

Add “private” methods and other internal data (i.e. non-reactive) to components in the created() hook.

16. Vue.js embedded in XML

Well-formed XML cannot use the : and @ shortcuts for v-bind: and v-on:. And in XML these attributes are interpreted as namespace names.

To use the v-bind: and v-on: syntax in XML (e.g. XSLT files), add these as dummy namespaces in the XML, e.g.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:v-bind="https://vuejs.org/v2/api/#v-bind"
  xmlns:v-on="https://vuejs.org/v2/api/#v-on">

Then also add the dummy xmlns:v-bind to the <html> element of the output – otherwise the definitions will be repeated everywhere.

17. Other good libraries to use

Good libraries to use alongside Vue.js are:

  • Lodash: a somewhat passable functional programming lib with good docs.
  • jQuery: it still works and you don’t need to throw it away.
  • Moment.js: sensible datetime manipulation.
  • vuejs-router: pretty good component-based router compared to the multitude of rubbish routers for Angular.js.
  • Bootstrap v4: The latest version uses flexbox, which is a revolution in web layout.