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
});
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>
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>`
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
});
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>
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
});
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>
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: '*'
to match all routes and:
path: '/user-*'
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
});
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>
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
});
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>
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
});
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>
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.