Vue.js is an easy to use web app framework that we can use to develop interactive front end apps.
Vue Router is a URL router that maps URLs to components.
In this article, we’ll look at how to pass props to route components with the Vue Router.
Passing Props
Using the $route
in our component creates a tight coupling between the $route
object and the component. Therefore, it limits the flexibility of the component as it can be only used on certain URLs.
We can decouple the component from the router by using the props
option.
For example, instead of writing:
const User = { template: "<div>User {{ $route.params.id }}</div>" };
const routes = [
{
path: "/user/:id",
component: User
}
];
const router = new VueRouter({
routes
});
new Vue({
el: "#app",
router
});
We instead write:
src/index.js
:
const User = { template: "<div>User {{ id }}</div>" };
const routes = \[
{
path: "/user/:id",
component: User,
props: true
}
\];const router = new VueRouter({
routes
});new Vue({
el: "#app",
router
});
src/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">
<router-view></router-view>
</div>
<script src="src/index.js"></script>
</body>
</html>
If we have multiple router-views
, then we have to define the props
on each one as follows:
src/index.js
:
const Foo = { props: ["id"], template: "<div>foo {{id}}</div>" };
const Bar = { props: ["id"], template: "<div>bar {{id}}</div>" };
const routes = [
{
path: "/:id",
components: { default: Foo, bar: Bar },
props: { default: true, bar: true }
}
];
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">
<router-view></router-view>
<router-view name="bar"></router-view>
</div>
<script src="src/index.js"></script>
</body>
</html>
Then when we go to /#/1
, we see:
foo 1bar 1
displayed.
As we can see when props
is set to true
, then $route.params
will be set as the component props.
This makes testing easier since we don’t have to worry about the $route
object when testing.
Object Mode
We can set the props
property to an object. This is handy for static props.
For example, we can do that as follows:
src/index.js
:
const Foo = { props: ["id"], template: "<div>foo {{id}}</div>" };
const routes = [
{
path: "/foo",
component: Foo,
props: { id: 1 }
}
];
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">
<router-view></router-view>
</div>
<script src="src/index.js"></script>
</body>
</html>
Then we see foo 1
displayed when we go to /#/foo
.
Function Mode
We can pass in a function that returns props. This lets us do whatever we want to with the route parameters before sending it to the component as props.
src/index.js
:
const Foo = { props: ["idString"], template: "<div>foo {{idString}}</div>" };
const routes = [
{
path: "/foo/:id",
component: Foo,
props: route => ({ idString: `id ${route.params.id}` })
}
];
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">
<router-view></router-view>
<router-view name="bar"></router-view>
</div>
<script src="src/index.js"></script>
</body>
</html>
In the code above, we set a function as the property of props
where we returned an object that sets the idString
property to `id ${route.params.id}`
.
Then our Foo
component accepts the idString
prop instead of getting id
straight from the route parameter. Therefore, we see the ‘id’ before the id
route parameter that we passed in since that’s what we returned.
So when we go to /#/foo/1
, we get foo id 1
displayed.
Conclusion
We can pass in route parameter to components as props instead of retrieving route parameters from the $route
object.
This makes testing easier and also makes the component more flexible since it decouples the component from the Vue Router.
We can set the props
property to true
to pass in a route parameter as a prop. For static props, we can set an object as the value of props
.
We can also set it as a function to manipulate the route parameter before returning an object where the value will be sent as props to the component and retrieved by the key of the returned object in the component.