What I Learned About VueJS From Building A Chrome Extension

What I Learned About VueJS From Building A Chrome Extension

I wanted to experiment with building a Google Chrome extension with Vue.js so I decided to take the Vue TodoMVC and try to make it accessible from my browser toolbar:

Building a browser extension with Vue is a very similar process to building a regular web page with Vue, but there are a few key differences which I’ll discuss in this article.

No templates

One thing we love about Vue is the ability to use templates either in a file:

<body>
  <div id="app">
    <div>{{ message }}</div>
  </div>
</body>

Or in a string:

new Vue({
  template: `<div>{{ message }}</div>`
});

One small problem: you can’t use templates like this in Chrome extensions!

But before you give up and go back to jQuery, it’s worth understanding why this limitation exists and how Vue can help you work around it.

read more

When VueJS Can't Help You

When VueJS Can't Help You

If you want to build a web page with JavaScript, VueJS can do one helluva job on it. But there’s a condition: it only works on parts of the page where it has unhampered control. Any part that might be interfered with by other scripts or plugins is a no-go for Vue.

This means the head and body tags are Vue-free zones. It’s a real bummer if you wanted Vue to manage a class on the body, to take one example.

But while Vue can’t directly manage the head or body tags, it can still help you to manage them through other means.

Vue’s beef with the head and body tags

Why is Vue picky about where it works?

Vue optimises page rendering through use of a virtual DOM. This is a JavaScript representation of the “real” DOM that Vue keeps in memory. DOM updates are often slow, so changes are made first to the virtual DOM, allowing Vue to optimise how it updates the real DOM through batching etc.

This system would be undermined if some third party were to make changes to the DOM without Vue’s knowledge causing a mismatch between the real DOM and the virtual DOM.

For this reason Vue will not attempt to control the whole page, but only a part of the page where it knows it will have unhampered control.

The mount element

The first thing we usually do in a Vue project is to give Vue a mount element in the configuration object via the el property:

new Vue({
  el: '#app'
});

read more

Use Any Javascript Library With Vue.js

Use Any Javascript Library With Vue.js

Lodash, Moment, Axios, Async…these are useful Javascript libraries that you’ll want to utilise in many of your Vue.js apps.

But as your project grows you’ll be separating code into single file components and module files. You also may want to run your app in different environments to allow server rendering.

Unless you find an easy and robust way to include those Javascript libraries across your components and module files they’re going to be a nuisance!

How not to include a library in a Vue.js project

Global variable

The naive way to add a library to your project is to make it a global variable by attaching it to the window object:

entry.js

window._ = require('lodash');

MyComponent.vue

export default {
  created() {
    console.log(_.isEmpty() ? 'Lodash everywhere!' : 'Uh oh..');
  }
}

The case against window variables is a long one, but, specifically to this discussion, they don’t work with server rendering. When the app runs on the server the window object will be undefined and so attempting to access a property will end with an error.

Importing in every file

Another second-rate method is to import the library into every file:

MyComponent.vue

import _ from 'lodash';

export default {
  created() {
    console.log(_.isEmpty() ? 'Lodash is available here!' : 'Uh oh..');
  }
}

This works, but it’s not very DRY and it’s basically just a pain: you have to remember to import it into every file, and remove it again if you stop using it in that file. And if you don’t setup your build tool correctly you may end up with multiple copies of the same library in your build.

A better way

read more

Don't Forget Browser Button UX In Your Vue.js App

Don't Forget Browser Button UX In Your Vue.js App

When building single-page applications many Vue developers forget about UX for browser button navigation. They mistakenly assume that this kind of navigtion is the same as hyperlink navigation when in fact it can be quite different.

Unlike hyperlink navigation, if a user goes forward and back between pages they expect the page to still look like it did when they return or they’ll consider the UX “weird” or “annoying”.

For example, if I were browsing a thread on Hacker News and I scroll down to a comment and collapse it, then I clicked though to another page, then I clicked “back”, I’d expect to still be scrolled down to the comment and for it to still be collapsed!

Hacker News comments

In a Vue.js app, though, this is not the default behaviour; scroll position and app data are not persisted by default. We need to consciously set up our app to ensure we have a smooth and predictable UX for the browser navigation buttons.

Configuring Vue Router

Vue Router’s role in optimal back and forward UX is in controlling scroll behavior. A user’s expectations with this would be:

read more

Faking Server-Side Rendering With Vue.js and Laravel

Faking Server-Side Rendering With Vue.js and Laravel

Server-side rendering (SSR) is a design concept for full-stack web apps that provides a rendered page to the browser. The idea is that the page can be shown while the user waits for scripts to be downloaded and run.

If you aren’t using a Node.js server for your app then you’re out of luck; only a Javascript server can render a Javascript app.

However, there are alternative to SSR that may be good enough, or even better, for some use cases. In this article I’m going to explain a method I use to “fake” server-side rendering using Vue.js and Laravel.

Pre-rendering

Pre-rendering (PR) tries to achieve the same outcome as SSR by using a headless browser to render the app and capture the output to an HTML file, which is then served to the browser. The differnce between this and SSR is that it is done ahead of time, not on-the-fly.

Limitation: user-specific content

Some pages, like the front page of your site, will probably contain general content i.e. content that all users will view the same. But other pages, like admin pages, will contain user-specific content, for example a user’s name and birth date.

The limitation of PR is that it can’t be used for pages that contain such content. As I just said, the pre-rendered templates are only made once and can’t be customised. SSR does not have this limitation.

Faking server-side rendering

My fake SSR method for Vue and Laravel is to pre-render a page, but replace any user-specific content with Laravel Blade tokens. When the page is served, Laravel’s view helper will replace the tokens with user-specific content.

So before pre-rendering your page will have this:

<div id="app"></div>

After pre-rendering you’ll have this:

<div id="app">
    <div>
        Hello {{ $name }}, your birthday is {{ $birthday }}
    </div>
</div>

And when the page is served by Laravel your browser receives the following, which is exactly what it would receive from SSR:

<div id="app" server-rendered="true">
    <div>
        Hello Anthony, your birthday is 25th October.
    </div>
</div>

With this method we get all the benefits of SSR but it can be done with a non-Node backend like Laravel.

read more