Vue Router 4 — Navigation

John Au-Yeung - Jan 25 '21 - - Dev Community

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.

Navigation

We can navigate to a route with the this.$router ‘s methods.

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">Go to Foo</router-link>
        <router-link to="/bar">Go to Bar</router-link>
        <a @click="goBack" href="#">Go Back</a>
      </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
      });

      const app = Vue.createApp({
        methods: {
          goBack() {
            window.history.length > 1
              ? this.$router.go(-1)
              : this.$router.push("/foo");
          }
        }
      });
      app.use(router);
      app.mount("#app");
    </script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

to create a goBack method and call it when we click on the Go Back link.

In the method, we check if there are anything in the browser history. 

If there is, then we go back to the previous page.

Otherwise, we go to the /foo page.

Reacting to Params Changes

We can react to route params changes in a few ways.

For instance, 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/1">Foo 1</router-link>
        <router-link to="/foo/2">Foo 2</router-link>
      </p>
      <router-view></router-view>
    </div>
    <script>
      const Foo = {
        template: "<div>foo</div>",
        watch: {
          $route(to, from) {
            console.log(to, from);
          }
        }
      };

      const routes = [{ path: "/foo/:id", component: Foo }];

      const router = VueRouter.createRouter({
        history: VueRouter.createWebHistory(),
        routes
      });

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

We have the /foo/:id route that maps to the Foo component.

And in the Foo component, we have the $route watcher to watch the route.

to has the route to go to. from has the route that we departed from.

They’re both objects with the path, route metadata, route parameters, query parameters, and more.

Also, we can use the beforeRouteUpdate method to watch for route changes:

<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="[https://unpkg.com/vue@next](https://unpkg.com/vue@next)"></script>
    <script src="[https://unpkg.com/vue-router@4.0.0-beta.7/dist/vue-router.global.js](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/1">Foo 1</router-link>
        <router-link to="/foo/2">Foo 2</router-link>
      </p>
      <router-view></router-view>
    </div>
    <script>
      const Foo = {
        template: "<div>foo</div>",
        beforeRouteUpdate(to, from, next) {
          console.log(to, from);
          next();
        }
      };

      const routes = [{ path: "/foo/:id", component: Foo }];

      const router = VueRouter.createRouter({
        history: VueRouter.createWebHistory(),
        routes
      });

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

Instead of watching the $route object, we have the beforeRouteUpdate hook, which is made available with the app.use(router) call.

Now when we click on the links, we’ll see the same data as we did with the watcher.

The only difference is that we call next to move to the next route.

Conclusion

We can watch for navigation with watchers or hooks with Vue Router 4.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .