DEV Community

John Au-Yeung
John Au-Yeung

Posted on • Originally published at thewebdev.info

Dynamic Route Matching with Vue Router

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.js is an easy to use web app framework that we can use to develop interactive front end apps.

In this article, we’ll look at how to match routes dynamically with Vue Router.

Route Parameters

We can get route parameters with the this.$route.params object.

For example, we can write an app that shows the URL parameter that’s passed in as follows:

src/index.js :

const User = {
  computed: {
    username() {
      return this.$route.params.username;
    }
  },
  template: `<div>{{username}}</div>`
};

const routes = [{ path: "/user/:username", component: User }];

const router = new VueRouter({
  routes
});

new Vue({
  el: "#app",
  router
});
Enter fullscreen mode Exit fullscreen mode

index.html :

<!DOCTYPE html>
<html>
  <head>
    <title>App</title>
    <meta charset="UTF-8" />
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
  </head>
  <body>
    <div id="app">
      <div>
        <router-link to="/user/foo">Foo</router-link>
        <router-link to="/user/bar">Bar</router-link>
      </div>
      <router-view></router-view>
    </div>
    <script src="src/index.js"></script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

The :username in “/user/:username” is the parameter, so we can get what passed in after /user/ by using this.$route.params.username .

We added a computed property username which returns this.$route.params.username so we can use:

`<div>{{username}}</div>`
Enter fullscreen mode Exit fullscreen mode

to show the username URL parameter.

We can also have multiple parameters in one route.

For example, we can write the following:

src/index.js :

const Name = {
  template: `<div>
    {{$route.params.firstName}}
    {{$route.params.lastName}}
  </div>`
};

const routes = [{ path: "/name/:firstName/:lastName", component: Name }];

const router = new VueRouter({
  routes
});

new Vue({
  el: "#app",
  router
});
Enter fullscreen mode Exit fullscreen mode

index.html :

<!DOCTYPE html>
<html>
  <head>
    <title>App</title>
    <meta charset="UTF-8" />
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
  </head>
  <body>
    <div id="app">
      <div>
        <router-link to="/name/Jane/Doe">Jane</router-link>
        <router-link to="/name/Mary/Smith">Mary</router-link>
      </div>
      <router-view></router-view>
    </div>
    <script src="src/index.js"></script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Then when we click on the links, we get the first name and last name that we passed into the URL parameters.

:firstName and :lastName are matched to the params by position.

Reacting to Params Changes

We can watch the $route object to watch for param changes. Routes that the same name but different params use the same components. They won’t be re-rendered from scratch, so the lifecycle hooks won’t be called.

For example, we can write the following:

src/index.js :

const Name = {
  data() {
    return {
      oldName: "",
      newName: ""
    };
  },
  watch: {
    $route(to, from) {
      this.oldName = from.params.name;
      this.newName = to.params.name;
    }
  },
  template: `<div>
    Old: {{oldName}}
    New: {{newName}}
  </div>`
};

const routes = [{ path: "/name/:name", component: Name }];

const router = new VueRouter({
  routes
});

new Vue({
  el: "#app",
  router
});
Enter fullscreen mode Exit fullscreen mode

index.html :

<!DOCTYPE html>
<html>
  <head>
    <title>App</title>
    <meta charset="UTF-8" />
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
  </head>
  <body>
    <div id="app">
      <div>
        <router-link to="/name/Jane">Jane</router-link>
        <router-link to="/name/Mary">Mary</router-link>
      </div>
      <router-view></router-view>
    </div>
    <script src="src/index.js"></script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

In the code above, we have the Name component that’s mapped to a route that takes the name route parameter.

Also, Name has watcher for the $route object that takes the to and from parameters. They are the previous and current routes respectively.

So when we click back and forth between links, we’ll see the old parameter and new parameter displayed.

Catch all / 404 Not found Route

We can add * as a wildcard character for routes.

For example, we can use:

path: '*'
Enter fullscreen mode Exit fullscreen mode

to match all routes and:

path: '/user-*'
Enter fullscreen mode Exit fullscreen mode

to match anything that begins with user- .

For example, we can use the wildcard character as follows:

src/index.js :

const Foo = { template: "<p>foo</p>" };
const Bar = { template: "<p>bar</p>" };
const NotFound = { template: "<p>not found</p>" };
const routes = [
  { path: "/foo", component: Foo },
  { path: "/bar", component: Bar },
  { path: "*", component: NotFound }
];

const router = new VueRouter({
  routes
});

new Vue({
  el: "#app",
  router
});
Enter fullscreen mode Exit fullscreen mode

index.html :

<!DOCTYPE html>
<html>
  <head>
    <title>App</title>
    <meta charset="UTF-8" />
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
  </head>
  <body>
    <div id="app">
      <div>
        <router-link to="/foo">Foo</router-link>
        <router-link to="/bar">Bar</router-link>
      </div>
      <router-view></router-view>
    </div>
    <script src="src/index.js"></script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

When we go to any URL other than /foo or /bar , we’ll see the ‘not found’ message.

We can use the wildcard character with other text as follows:

src/index.js :

const Foo = { template: "<p>foo</p>" };
const Bar = { template: "<p>bar</p>" };
const routes = [
  { path: "/foo*", component: Foo },
  { path: "/bar", component: Bar }
];

const router = new VueRouter({
  routes
});

new Vue({
  el: "#app",
  router
});
Enter fullscreen mode Exit fullscreen mode

index.html :

<!DOCTYPE html>
<html>
  <head>
    <title>App</title>
    <meta charset="UTF-8" />
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
  </head>
  <body>
    <div id="app">
      <div>
        <router-link to="/foo">Foo</router-link>
        <router-link to="/bar">Bar</router-link>
      </div>
      <router-view></router-view>
    </div>
    <script src="src/index.js"></script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Then we see foo when we go to any URL that starts with foo .

Regular Expressions

We can use regular expressions to match route parameters. For example, we can write:

src/index.js :

const Foo = { template: "<p>foo {{$route.params.id}}</p>" };
const Bar = { template: "<p>bar</p>" };
const routes = [
  { path: "/foo/:id(d+)", component: Foo },
  { path: "/bar", component: Bar }
];

const router = new VueRouter({
  routes
});

new Vue({
  el: "#app",
  router
});
Enter fullscreen mode Exit fullscreen mode

index.html :

<!DOCTYPE html>
<html>
  <head>
    <title>App</title>
    <meta charset="UTF-8" />
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
  </head>
  <body>
    <div id="app">
      <div>
        <router-link to="/foo">Foo</router-link>
        <router-link to="/bar">Bar</router-link>
      </div>
      <router-view></router-view>
    </div>
    <script src="src/index.js"></script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Then when we go to /foo/1 we see foo 1 . If what comes after /foo/ isn’t a number, then we won’t see anything.

Conclusion

We can pass in route parameters by prefix whatever we want to pass in with a colon, then we can get it from the this.$route.params object.

The asterisk is a wildcard character that matches any URLs that don’t match the routes listed. We can also combine it with other text to match patterns that we want to match.

Finally, we can use regex to match route parameters.

Top comments (0)