Vue Router 4–Navigation Guard Hooks
Tags: webdev, programming, javascript, vue
Published: 2021-01-25 23:29:33

**Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62**

**Subscribe to my email list now at http://jauyeung.net/subscribe/**


**Vue Router 4 is in beta and it’s subject to change.**

To build a single page app easily, we got to add routing so that URLs will be mapped to components that are rendered.

In this article, we’ll look at how to use Vue Router 4 with Vue 3.

### Global After Hooks

We can create global after navigation hooks.

To do that, we call the `router.afterEach` method with a callback.

For example, we can write:

```
<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://unpkg.com/vue-router@4.0.0-beta.7/dist/vue-router.global.js"></script>
    <title>App</title>
  </head>
  <body>
    <div id="app">
      <p>
        <router-link to="/foo">foo</router-link>
        <router-link to="/bar">bar</router-link>
      </p>
      <router-view></router-view>
    </div>
    <script>
      const Foo = {
        template: "<div>foo</div>"
      };
      const Bar = {
        template: "<div>bar</div>"
      };
      const routes = [
        {
          path: "/foo",
          component: Foo
        },
        {
          path: "/bar",
          component: Bar
        }
      ];
      const router = VueRouter.createRouter({
        history: VueRouter.createWebHistory(),
        routes
      });

      router.afterEach((to, from) => {
        console.log(to, from);
      });
      const app = Vue.createApp({});
      app.use(router);
      app.mount("#app");
    </script>
  </body>
</html>
```

to add our after navigation hook.

It’s called after we navigated to the route.

`to` is a route object being navigated to.

`from` is a route object being navigated away from.

A route object has the `fullPath` , metadata, query parameters, URL parameters, and more.

There’s no `next` function to let us do redirects or throw errors.

### Per-Route Guard

We can add navigation guards per route.

For example, we can write:

```
<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://unpkg.com/vue-router@4.0.0-beta.7/dist/vue-router.global.js"></script>
    <title>App</title>
  </head>
  <body>
    <div id="app">
      <p>
        <router-link to="/foo">foo</router-link>
        <router-link to="/bar">bar</router-link>
      </p>
      <router-view></router-view>
    </div>
    <script>
      const Foo = {
        template: "<div>foo</div>"
      };
      const Bar = {
        template: "<div>bar</div>"
      };
      const routes = [
        {
          path: "/foo",
          component: Foo
        },
        {
          path: "/bar",
          component: Bar,
          beforeEnter: (to, from, next) => {
            console.log(to, from);
            next();
          }
        }
      ];
      const router = VueRouter.createRouter({
        history: VueRouter.createWebHistory(),
        routes
      });

      const app = Vue.createApp({});
      app.use(router);
      app.mount("#app");
    </script>
  </body>
</html>
```

We have the `beforeEnter` method in the `/bar` route object.

The `next` function lets us resolve the navigation since it’s run before we enter the route.

### In-Component Guards

We can add navigation guards inside a component.

For example, we can write:

```
<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://unpkg.com/vue-router@4.0.0-beta.7/dist/vue-router.global.js"></script>
    <title>App</title>
  </head>
  <body>
    <div id="app">
      <p>
        <router-link to="/foo">foo</router-link>
        <router-link to="/bar">bar</router-link>
      </p>
      <router-view></router-view>
    </div>
    <script>
      const Foo = {
        template: "<div>foo</div>"
      };
      const Bar = {
        template: "<div>bar</div>",
        beforeEnter(to, from, next) {
          console.log(to, from);
          next();
        },
        beforeRouteUpdate(to, from, next) {
          console.log(to, from);
          next();
        },
        beforeRouteLeave(to, from, next) {
          console.log(to, from);
          next();
        }
      };
      const routes = [
        {
          path: "/foo",
          component: Foo
        },
        {
          path: "/bar",
          component: Bar
        }
      ];
      const router = VueRouter.createRouter({
        history: VueRouter.createWebHistory(),
        routes
      });

      const app = Vue.createApp({});
      app.use(router);
      app.mount("#app");
    </script>
  </body>
</html>
```

to add the navigation guards to our `Bar` component.

The `beforeRouteEnter` method is called before that renders the component is confirmed.

It doesn’t have access to `this` component instance since it hasn’t been created yet.

The `beforeRouterUpdate` method is called when the route that renders the component has changed.

For instance, when a route with dynamic parameters changed, then it’ll be run.

It has access to the `this` component instance.

`beforeRouterLeave` is called when the route that renders the component is about to be navigated from.

It also has access to the `this` component instance.

### Conclusion

We can add navigation guard hooks in various locations with Vue Router 4.