Yes, this is how vue-router guards work & when to use them

Futari Boy - developer & indie hacker
ITNEXT
Published in
3 min readDec 15, 2018

--

HO HO HO! Merry Christmas! Yes, I know it’s too early but, I won’t be writing any story before the 25th of December, so Merry Christmas by advance.

Now, lets deep dive into the main subject: Vue Router Guards.

What is Vue Router?

If you already know the answer, skip to the next title. For others, Vue Router also known as vue-router on github, is the official third-party plugin used to handle Routing / URL state for Vue JS apps.

What are Vue Router guards ?

Basically, Vue Router only switches components for you depending on the URL. It does not handle AJAX calls to the server or role-based auth protection for example. Why? Simply because it’s not what it was created for.

BUT! It has guards, that we can also call hooks, where you can plug onto.

Vue Router has 3 types of guards:

  • Global guards (on the instance)
    - These are called each time the URL changes
    - Guards: beforeEach, beforeResolve, afterEach
  • Route guards (on route definitions)
    - These are only called when the associated ROUTE is matched
    - Guards: beforeEnter
  • Route Component guards
    - These are only called when a ROUTE COMPONENT is used/unused
    - Guards: beforeRouteEnter, beforeRouteUpdate, beforeRouteLeave

NOTE: All guards except afterEach are “asynchronous”. They are called in sequence, therefore, you need to explicitly call the “next()” method to tell the router that you are done and that he can continue the sequence.
This is also known as the middleware pattern.

In other words, guards can prevent or confirm a URL change.

NOTE 2: Only components associated to routes will have their guards called. Children components that do not figure in a route definition will not have their guards called as the router is not aware of them.

When to use each of them?

First, let’s see in which order they are called.
Assuming we are navigating from “/” to “/contact”:

  1. beforeRouteLeave — called on the “/” route component
  2. beforeEach — called globally when a new navigation starts
  3. beforeEnter — called when “/contact” route matches
  4. beforeRouteEnter — called when “/contact” route component matches
  5. beforeResolve — called globally when route component guards are done
  6. afterEach — called globally when everything is resolved

Now, assuming we are navigating from “/page/1” to “/page/2”, the same route and component will be reused, only the URL changes:

  1. beforeEach — called globally when a new navigation starts
  2. beforeRouteUpdate — called on the route component when it’s reused
  3. beforeResolve — called globally when route component guards are done
  4. afterEach — called globally when everything is resolved

NOTE: When a route component is reused, all “enter” guards are skipped.

Now that we’ve seen in which order they are executed, it’s easy to imagine when to use each:

  • Global guards:
    - Use them when you have common logic regardless of the route
    - beforeEach: actions before entering any route (role-based protection…)
    - beforeResolve: actions after route component guards are done
    - afterEach: actions to do when you are sure the route component will be instantiated because the route is fully resolved (tracking page views…)
  • Route guards:
    - Instead of using a global guard and adding multiple conditions in it, use a route guard if the logic is only for a specific route
    - beforeEnter: pre-fetching data to set on the store, any route-specific action whether sync or async
  • Route Component guards:
    - Use them when you need to have access to the component instance
    - beforeRouteEnter: fetching date before component is rendered
    - beforeRouteUpdate: updating local data when the URL changes but the component is reused, handling component data caching
    - beforeRouteLeave: preventing the user to leave the route component

That’s pretty much it. I hope you now understand the differences between all those guards and why to use them.

Most of the use-cases will be for data-fetching, analytics, auth, layout systems or anything else based on the URL.

Here’s a jsfiddle with all the guards added to see how the sequence goes:
https://jsfiddle.net/darkylmnx/xo5ra1jt/
Here’s another jsfiddle with async guards to compare:
https://jsfiddle.net/darkylmnx/xo5ra1jt/2/

Open the console to see it.

PS: Winter is Coming.
Get a developer sweater to stay warm https://maisonfutari.com
If it’s sunny where you are (hello Miami!) We have t-shirts too :)

--

--

Developer, nomad, SaaS & micro-SaaS founder 👋 #indiehacker 👨‍💻 #freelance 🇯🇵 #anime #japan